mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Extract search and replace component
This commit is contained in:
+17
-12
@@ -19,7 +19,9 @@ import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
|
||||
public class EditorSearchComponentTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
public class EditorSearchTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
private static final String THE_CODE = "public class A {\n" +
|
||||
" //First comment ABC, ABCD, abc\n" +
|
||||
" int ABC = 3;\n" +
|
||||
@@ -34,18 +36,18 @@ public class EditorSearchComponentTest extends LightPlatformCodeInsightFixtureTe
|
||||
myFixture.getEditor().getSelectionModel().setSelection(i, i+key.length());
|
||||
myFixture.performEditorAction("Find");
|
||||
IdeEventQueue.getInstance().flushQueue();
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getText());
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getSelectedText());
|
||||
assertEquals(3, getEditorSearchComponent().getSearchTextComponent().getCaretPosition());
|
||||
assertEquals(key, getSearchTextComponent().getText());
|
||||
assertEquals(key, getSearchTextComponent().getSelectedText());
|
||||
assertEquals(3, getSearchTextComponent().getCaretPosition());
|
||||
assertTrue(getEditorSearchComponent().hasMatches());
|
||||
IdeFocusManager.findInstance().requestFocus(myFixture.getEditor().getContentComponent(), false);
|
||||
IdeEventQueue.getInstance().flushQueue();
|
||||
|
||||
myFixture.performEditorAction("Find");
|
||||
IdeEventQueue.getInstance().flushQueue();
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getText());
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getSelectedText());
|
||||
assertEquals(key.length(), getEditorSearchComponent().getSearchTextComponent().getCaretPosition());
|
||||
assertEquals(key, getSearchTextComponent().getText());
|
||||
assertEquals(key, getSearchTextComponent().getSelectedText());
|
||||
assertEquals(key.length(), getSearchTextComponent().getCaretPosition());
|
||||
|
||||
getEditorSearchComponent().close();
|
||||
|
||||
@@ -55,14 +57,17 @@ public class EditorSearchComponentTest extends LightPlatformCodeInsightFixtureTe
|
||||
IdeEventQueue.getInstance().flushQueue();
|
||||
myFixture.performEditorAction("Find");
|
||||
IdeEventQueue.getInstance().flushQueue();
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getText());
|
||||
assertEquals(key, getEditorSearchComponent().getSearchTextComponent().getSelectedText());
|
||||
assertEquals(key.length(), getEditorSearchComponent().getSearchTextComponent().getCaretPosition());
|
||||
assertEquals(key, getSearchTextComponent().getText());
|
||||
assertEquals(key, getSearchTextComponent().getSelectedText());
|
||||
assertEquals(key.length(), getSearchTextComponent().getCaretPosition());
|
||||
|
||||
}
|
||||
|
||||
private EditorSearchComponent getEditorSearchComponent() {
|
||||
return (EditorSearchComponent)myFixture.getEditor().getHeaderComponent();
|
||||
private EditorSearchSession getEditorSearchComponent() {
|
||||
return EditorSearchSession.get(myFixture.getEditor());
|
||||
}
|
||||
|
||||
private JTextComponent getSearchTextComponent() {
|
||||
return getEditorSearchComponent().getComponent().getSearchTextComponent();
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,8 @@ package com.intellij.find;
|
||||
|
||||
import com.intellij.find.editorHeaderActions.*;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.ide.impl.DataManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.testFramework.fixtures.EditorMouseFixture;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
@@ -138,9 +137,9 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
|
||||
}
|
||||
|
||||
private void setTextToFind(String text) {
|
||||
EditorSearchComponent editorSearchComponent = getEditorSearchComponent();
|
||||
assertNotNull(editorSearchComponent);
|
||||
JTextComponent searchField = editorSearchComponent.getSearchTextComponent();
|
||||
EditorSearchSession editorSearchSession = getEditorSearchComponent();
|
||||
assertNotNull(editorSearchSession);
|
||||
JTextComponent searchField = editorSearchSession.getComponent().getSearchTextComponent();
|
||||
assertNotNull(searchField);
|
||||
for (int i = 0; i <= text.length(); i++) {
|
||||
searchField.setText(text.substring(0, i)); // emulate typing chars one by one
|
||||
@@ -149,25 +148,23 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
|
||||
}
|
||||
|
||||
private void nextOccurrence() {
|
||||
final EditorSearchComponent editorSearchComponent = getEditorSearchComponent();
|
||||
executeAction(new NextOccurrenceAction(editorSearchComponent, editorSearchComponent.getSearchTextComponent(), true));
|
||||
executeHeaderAction(EditorSearchSession.createNextOccurrenceAction());
|
||||
}
|
||||
|
||||
private void prevOccurrence() {
|
||||
final EditorSearchComponent editorSearchComponent = getEditorSearchComponent();
|
||||
executeAction(new PrevOccurrenceAction(editorSearchComponent, editorSearchComponent.getSearchTextComponent()));
|
||||
executeHeaderAction(EditorSearchSession.createPrevOccurrenceAction());
|
||||
}
|
||||
|
||||
private void addOccurrence() {
|
||||
executeAction(new AddOccurrenceAction(getEditorSearchComponent()));
|
||||
executeHeaderAction(new AddOccurrenceAction());
|
||||
}
|
||||
|
||||
private void removeOccurrence() {
|
||||
executeAction(new RemoveOccurrenceAction(getEditorSearchComponent()));
|
||||
executeHeaderAction(new RemoveOccurrenceAction());
|
||||
}
|
||||
|
||||
private void allOccurrences() {
|
||||
executeAction(new SelectAllAction(getEditorSearchComponent()));
|
||||
executeHeaderAction(new SelectAllAction());
|
||||
}
|
||||
|
||||
private void nextOccurrenceFromEditor() {
|
||||
@@ -191,20 +188,21 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
|
||||
}
|
||||
|
||||
private void closeFind() {
|
||||
EditorSearchComponent editorSearchComponent = getEditorSearchComponent();
|
||||
executeAction(new CloseOnESCAction(editorSearchComponent, editorSearchComponent.getSearchTextComponent()));
|
||||
EditorSearchSession editorSearchSession = getEditorSearchComponent();
|
||||
editorSearchSession.close();
|
||||
}
|
||||
|
||||
private static void executeAction(EditorHeaderAction action) {
|
||||
action.actionPerformed(AnActionEvent.createFromInputEvent(action, null, ActionPlaces.EDITOR_TOOLBAR));
|
||||
private void executeHeaderAction(AnAction action) {
|
||||
DataContext context = new DataManagerImpl.MyDataContext(getEditorSearchComponent().getComponent());
|
||||
action.actionPerformed(AnActionEvent.createFromDataContext(ActionPlaces.EDITOR_TOOLBAR, null, context));
|
||||
}
|
||||
|
||||
private void initFind() {
|
||||
myFixture.performEditorAction("Find");
|
||||
}
|
||||
|
||||
private EditorSearchComponent getEditorSearchComponent() {
|
||||
return (EditorSearchComponent)myFixture.getEditor().getHeaderComponent();
|
||||
private EditorSearchSession getEditorSearchComponent() {
|
||||
return EditorSearchSession.get(myFixture.getEditor());
|
||||
}
|
||||
|
||||
private void init(String text) {
|
||||
|
||||
+4
-8
@@ -20,7 +20,7 @@ import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.IdentifierUtil;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
@@ -56,7 +56,6 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
public class HighlightUsagesHandler extends HighlightHandlerBase {
|
||||
@@ -192,9 +191,8 @@ public class HighlightUsagesHandler extends HighlightHandlerBase {
|
||||
editor = ((EditorWindow)editor).getDelegate();
|
||||
}
|
||||
|
||||
final JComponent oldHeader = editor.getHeaderComponent();
|
||||
if (oldHeader instanceof EditorSearchComponent) {
|
||||
final EditorSearchComponent oldSearch = (EditorSearchComponent)oldHeader;
|
||||
EditorSearchSession oldSearch = EditorSearchSession.get(editor);
|
||||
if (oldSearch != null) {
|
||||
if (oldSearch.hasMatches()) {
|
||||
String oldText = oldSearch.getTextInField();
|
||||
if (!oldSearch.getFindModel().isRegularExpressions()) {
|
||||
@@ -208,9 +206,7 @@ public class HighlightUsagesHandler extends HighlightHandlerBase {
|
||||
}
|
||||
}
|
||||
|
||||
final EditorSearchComponent header = new EditorSearchComponent(editor, project);
|
||||
header.getFindModel().setRegularExpressions(false);
|
||||
editor.setHeaderComponent(header);
|
||||
EditorSearchSession.start(editor, project).getFindModel().setRegularExpressions(false);
|
||||
}
|
||||
|
||||
public static class DoHighlightRunnable implements Runnable {
|
||||
|
||||
@@ -1,878 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.find;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.editorHeaderActions.*;
|
||||
import com.intellij.find.impl.livePreview.LivePreviewController;
|
||||
import com.intellij.find.impl.livePreview.SearchResults;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.DefaultCustomComponentAction;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.event.SelectionEvent;
|
||||
import com.intellij.openapi.editor.event.SelectionListener;
|
||||
import com.intellij.openapi.editor.impl.EditorHeaderComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.LightColors;
|
||||
import com.intellij.ui.OnePixelSplitter;
|
||||
import com.intellij.ui.SearchTextField;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.labels.LinkLabel;
|
||||
import com.intellij.ui.components.labels.LinkListener;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchSupply;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author max, andrey.zaytsev
|
||||
*/
|
||||
public class EditorSearchComponent extends EditorHeaderComponent implements DataProvider, SelectionListener, SearchResults.SearchResultsListener {
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
private JPanel myLeftPanel;
|
||||
private JTextComponent mySearchTextComponent;
|
||||
private Wrapper mySearchFieldWrapper;
|
||||
|
||||
private JTextComponent myReplaceTextComponent;
|
||||
private Wrapper myReplaceFieldWrapper;
|
||||
|
||||
|
||||
private JPanel myRightPanel;
|
||||
private ActionToolbarImpl mySearchActionsToolbar1;
|
||||
private ActionToolbarImpl mySearchActionsToolbar2;
|
||||
private JLabel myMatchInfoLabel;
|
||||
private LinkLabel<Object> myClickToHighlightLabel;
|
||||
|
||||
private ActionToolbarImpl myReplaceActionsToolbar1;
|
||||
private ActionToolbarImpl myReplaceActionsToolbar2;
|
||||
private JPanel myReplaceToolbarWrapper;
|
||||
|
||||
@NotNull
|
||||
private final Editor myEditor;
|
||||
|
||||
public JTextComponent getSearchTextComponent() {
|
||||
return mySearchTextComponent;
|
||||
}
|
||||
|
||||
public JTextComponent getReplaceTextComponent() {
|
||||
return myReplaceTextComponent;
|
||||
}
|
||||
|
||||
private final Color myDefaultBackground;
|
||||
|
||||
private final LivePreviewController myLivePreviewController;
|
||||
private final SearchResults mySearchResults;
|
||||
|
||||
private final FindModel myFindModel;
|
||||
|
||||
public EditorSearchComponent(@NotNull Editor editor, Project project) {
|
||||
this(editor, project, createDefaultFindModel(project, editor));
|
||||
}
|
||||
|
||||
public EditorSearchComponent(@NotNull final Editor editor, final Project project, FindModel findModel) {
|
||||
myFindModel = findModel;
|
||||
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
|
||||
mySearchResults = new SearchResults(myEditor, myProject);
|
||||
myLivePreviewController = new LivePreviewController(mySearchResults, this);
|
||||
|
||||
myDefaultBackground = new JTextField().getBackground();
|
||||
initUI();
|
||||
|
||||
new SwitchToFind(this);
|
||||
new SwitchToReplace(this);
|
||||
|
||||
myFindModel.addObserver(new FindModel.FindModelObserver() {
|
||||
@Override
|
||||
public void findModelChanged(FindModel findModel) {
|
||||
String stringToFind = myFindModel.getStringToFind();
|
||||
if (!wholeWordsApplicable(stringToFind)) {
|
||||
myFindModel.setWholeWordsOnly(false);
|
||||
}
|
||||
updateUIWithFindModel();
|
||||
updateResults(true);
|
||||
syncFindModels(FindManager.getInstance(myProject).getFindInFileModel(), myFindModel);
|
||||
}
|
||||
});
|
||||
|
||||
updateUIWithFindModel();
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
initLivePreview();
|
||||
}
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
private static FindModel createDefaultFindModel(Project project, Editor editor) {
|
||||
FindModel findModel = new FindModel();
|
||||
findModel.copyFrom(FindManager.getInstance(project).getFindInFileModel());
|
||||
if (editor.getSelectionModel().hasSelection()) {
|
||||
String selectedText = editor.getSelectionModel().getSelectedText();
|
||||
if (selectedText != null) {
|
||||
findModel.setStringToFind(selectedText);
|
||||
}
|
||||
}
|
||||
findModel.setPromptOnReplace(false);
|
||||
return findModel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getData(@NonNls final String dataId) {
|
||||
if (SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.is(dataId)) {
|
||||
return mySearchTextComponent.getText();
|
||||
}
|
||||
if (CommonDataKeys.EDITOR_EVEN_IF_INACTIVE.is(dataId)) {
|
||||
return myEditor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchResultsUpdated(SearchResults sr) {
|
||||
if (mySearchTextComponent.getText().isEmpty()) {
|
||||
updateUIWithEmptyResults();
|
||||
} else {
|
||||
int count = sr.getMatchesCount();
|
||||
boolean notTooMuch = count <= mySearchResults.getMatchesLimit();
|
||||
myMatchInfoLabel.setText(notTooMuch
|
||||
? ApplicationBundle.message("editorsearch.matches", count)
|
||||
: ApplicationBundle.message("editorsearch.toomuch", mySearchResults.getMatchesLimit()));
|
||||
myClickToHighlightLabel.setVisible(!notTooMuch);
|
||||
if (notTooMuch) {
|
||||
if (count > 0) {
|
||||
setRegularBackground();
|
||||
}
|
||||
else {
|
||||
setNotFoundBackground();
|
||||
}
|
||||
}
|
||||
else {
|
||||
setRegularBackground();
|
||||
}
|
||||
}
|
||||
myReplaceActionsToolbar1.updateActionsImmediately();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cursorMoved() {
|
||||
myReplaceActionsToolbar1.updateActionsImmediately();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFinished() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initUI() {
|
||||
myLeftPanel = new NonOpaquePanel(new BorderLayout());
|
||||
myLeftPanel.add(mySearchFieldWrapper = new Wrapper(), BorderLayout.NORTH);
|
||||
myLeftPanel.add(myReplaceFieldWrapper = new Wrapper(), BorderLayout.CENTER);
|
||||
|
||||
updateSearchComponent();
|
||||
updateReplaceComponent();
|
||||
initSearchToolbars();
|
||||
initReplaceToolBars();
|
||||
|
||||
Wrapper searchToolbarWrapper1 = new NonOpaquePanel(new BorderLayout());
|
||||
searchToolbarWrapper1.add(mySearchActionsToolbar1, BorderLayout.WEST);
|
||||
Wrapper searchToolbarWrapper2 = new Wrapper(mySearchActionsToolbar2);
|
||||
mySearchActionsToolbar2.setBorder(JBUI.Borders.emptyLeft(16));
|
||||
JPanel searchPair = new NonOpaquePanel(new BorderLayout()).setVerticalSizeReferent(mySearchFieldWrapper);
|
||||
searchPair.add(searchToolbarWrapper1, BorderLayout.WEST);
|
||||
searchPair.add(searchToolbarWrapper2, BorderLayout.CENTER);
|
||||
JLabel closeLabel = new JLabel(null, AllIcons.Actions.Cross, SwingConstants.RIGHT);
|
||||
closeLabel.setBorder(JBUI.Borders.empty(5));
|
||||
closeLabel.setVerticalAlignment(SwingConstants.TOP);
|
||||
closeLabel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
closeLabel.setToolTipText("Close search bar (Escape)");
|
||||
searchPair.add(new Wrapper.North(closeLabel), BorderLayout.EAST);
|
||||
|
||||
Wrapper replaceToolbarWrapper1 = new Wrapper(myReplaceActionsToolbar1).setVerticalSizeReferent(myReplaceFieldWrapper);
|
||||
Wrapper replaceToolbarWrapper2 = new Wrapper(myReplaceActionsToolbar2).setVerticalSizeReferent(myReplaceFieldWrapper);
|
||||
myReplaceActionsToolbar2.setBorder(JBUI.Borders.emptyLeft(16));
|
||||
|
||||
myReplaceToolbarWrapper = new NonOpaquePanel(new BorderLayout());
|
||||
myReplaceToolbarWrapper.add(replaceToolbarWrapper1, BorderLayout.WEST);
|
||||
myReplaceToolbarWrapper.add(replaceToolbarWrapper2, BorderLayout.CENTER);
|
||||
|
||||
searchToolbarWrapper1.setHorizontalSizeReferent(replaceToolbarWrapper1);
|
||||
|
||||
myRightPanel = new NonOpaquePanel(new BorderLayout());
|
||||
myRightPanel.add(searchPair, BorderLayout.NORTH);
|
||||
myRightPanel.add(myReplaceToolbarWrapper, BorderLayout.CENTER);
|
||||
|
||||
OnePixelSplitter splitter = new OnePixelSplitter(false, .25F);
|
||||
splitter.setFirstComponent(myLeftPanel);
|
||||
splitter.setSecondComponent(myRightPanel);
|
||||
splitter.setHonorComponentsMinimumSize(true);
|
||||
splitter.setAndLoadSplitterProportionKey("FindSplitterProportion");
|
||||
splitter.setOpaque(false);
|
||||
splitter.getDivider().setOpaque(false);
|
||||
add(splitter, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private void updateSearchComponent() {
|
||||
final int oldCaretPosition = mySearchTextComponent != null ? mySearchTextComponent.getCaretPosition() : 0;
|
||||
boolean wasNull = mySearchTextComponent == null;
|
||||
String textToSet = myFindModel.getStringToFind();
|
||||
if (!updateTextComponent(true)) {
|
||||
if (!mySearchTextComponent.getText().equals(textToSet)) {
|
||||
mySearchTextComponent.setText(textToSet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mySearchTextComponent.getText().equals(textToSet)) {
|
||||
mySearchTextComponent.setText(textToSet);
|
||||
if (wasNull) {
|
||||
mySearchTextComponent.selectAll();
|
||||
}
|
||||
}
|
||||
mySearchTextComponent.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searchFieldDocumentChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
mySearchTextComponent.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
if (StringUtil.isEmpty(mySearchTextComponent.getText())) {
|
||||
close();
|
||||
}
|
||||
else {
|
||||
requestFocus(myEditor.getContentComponent());
|
||||
addTextToRecent(EditorSearchComponent.this.mySearchTextComponent);
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_FOCUSED);
|
||||
if (!wasNull) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mySearchTextComponent.setCaretPosition(oldCaretPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
new RestorePreviousSettingsAction(this, mySearchFieldWrapper);
|
||||
new VariantsCompletionAction(mySearchTextComponent); // It registers a shortcut set automatically on construction
|
||||
}
|
||||
|
||||
private void searchFieldDocumentChanged() {
|
||||
setMatchesLimit(LivePreviewController.MATCHES_LIMIT);
|
||||
String text = mySearchTextComponent.getText();
|
||||
myFindModel.setStringToFind(text);
|
||||
if (!StringUtil.isEmpty(text)) {
|
||||
updateResults(true);
|
||||
}
|
||||
else {
|
||||
nothingToSearchFor();
|
||||
}
|
||||
if (mySearchTextComponent instanceof JTextArea) {
|
||||
adjustRows((JTextArea)mySearchTextComponent);
|
||||
}
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
private void updateMultiLineStateIfNeed() {
|
||||
myFindModel.setMultiline(mySearchTextComponent.getText().contains("\n") || myReplaceTextComponent.getText().contains("\n"));
|
||||
}
|
||||
|
||||
|
||||
private void updateReplaceComponent() {
|
||||
final int oldCaretPosition = myReplaceTextComponent != null ? myReplaceTextComponent.getCaretPosition() : 0;
|
||||
if (!updateTextComponent(false)) {
|
||||
return;
|
||||
}
|
||||
myReplaceTextComponent.setText(myFindModel.getStringToReplace());
|
||||
|
||||
myReplaceTextComponent.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
replaceFieldDocumentChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!getFindModel().isMultiline()) {
|
||||
new ReplaceOnEnterAction(this, myReplaceTextComponent);
|
||||
}
|
||||
|
||||
//myReplaceTextComponent.setText(myFindModel.getStringToReplace());
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myReplaceTextComponent.setCaretPosition(oldCaretPosition);
|
||||
}
|
||||
});
|
||||
|
||||
new VariantsCompletionAction(myReplaceTextComponent);
|
||||
new NextOccurrenceAction(this, myReplaceFieldWrapper, false);
|
||||
new PrevOccurrenceAction(this, myReplaceFieldWrapper);
|
||||
myReplaceFieldWrapper.revalidate();
|
||||
myReplaceFieldWrapper.repaint();
|
||||
}
|
||||
|
||||
private void replaceFieldDocumentChanged() {
|
||||
setMatchesLimit(LivePreviewController.MATCHES_LIMIT);
|
||||
myFindModel.setStringToReplace(myReplaceTextComponent.getText());
|
||||
if (myReplaceTextComponent instanceof JTextArea) {
|
||||
adjustRows((JTextArea)myReplaceTextComponent);
|
||||
}
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
private void initSearchToolbars() {
|
||||
DefaultActionGroup actionGroup1 = new DefaultActionGroup("search bar 1", false);
|
||||
mySearchActionsToolbar1 = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup1, true);
|
||||
mySearchActionsToolbar1.setForceMinimumSize(true);
|
||||
mySearchActionsToolbar1.setReservePlaceAutoPopupIcon(false);
|
||||
mySearchActionsToolbar1.setSecondaryButtonPopupStateModifier(new ActionToolbarImpl.PopupStateModifier() {
|
||||
@Override
|
||||
public int getModifiedPopupState() {
|
||||
return ActionButtonComponent.PUSHED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willModify() {
|
||||
return myFindModel.getSearchContext() != FindModel.SearchContext.ANY;
|
||||
}
|
||||
});
|
||||
mySearchActionsToolbar1.setSecondaryActionsTooltip("More Options(" + ShowMoreOptions.SHORT_CUT + ")");
|
||||
|
||||
|
||||
actionGroup1.add(new PrevOccurrenceAction(this, mySearchFieldWrapper));
|
||||
actionGroup1.add(new NextOccurrenceAction(this, mySearchFieldWrapper, true));
|
||||
actionGroup1.add(new FindAllAction(this));
|
||||
actionGroup1.addSeparator();
|
||||
actionGroup1.add(new AddOccurrenceAction(this));
|
||||
actionGroup1.add(new RemoveOccurrenceAction(this));
|
||||
actionGroup1.add(new SelectAllAction(this));
|
||||
//actionGroup1.addSeparator();
|
||||
//actionGroup1.add(new ToggleMultiline(this));//todo get rid of it!
|
||||
actionGroup1.addSeparator();
|
||||
|
||||
actionGroup1.addAction(new ToggleInCommentsAction(this)).setAsSecondary(true);
|
||||
actionGroup1.addAction(new ToggleInLiteralsOnlyAction(this)).setAsSecondary(true);
|
||||
actionGroup1.addAction(new ToggleExceptCommentsAction(this)).setAsSecondary(true);
|
||||
actionGroup1.addAction(new ToggleExceptLiteralsAction(this)).setAsSecondary(true);
|
||||
actionGroup1.addAction(new ToggleExceptCommentsAndLiteralsAction(this)).setAsSecondary(true);
|
||||
|
||||
DefaultActionGroup actionGroup2 = new DefaultActionGroup("search bar 2", false);
|
||||
mySearchActionsToolbar2 = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup2, true);
|
||||
actionGroup2.add(new ToggleMatchCase(this));
|
||||
actionGroup2.add(new ToggleRegex(this));
|
||||
actionGroup2.add(new ToggleWholeWordsOnlyAction(this));
|
||||
|
||||
myMatchInfoLabel = new JLabel() {
|
||||
@Override
|
||||
public Font getFont() {
|
||||
Font font = super.getFont();
|
||||
return font != null ? font.deriveFont(Font.BOLD) : null;
|
||||
}
|
||||
|
||||
};
|
||||
myMatchInfoLabel.setBorder(JBUI.Borders.empty(2, 20, 0, 20));
|
||||
|
||||
myClickToHighlightLabel = new LinkLabel<Object>("Click to highlight", null, new LinkListener<Object>() {
|
||||
@Override
|
||||
public void linkSelected(LinkLabel aSource, Object aLinkData) {
|
||||
setMatchesLimit(Integer.MAX_VALUE);
|
||||
updateResults(true);
|
||||
}
|
||||
});
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
|
||||
mySearchActionsToolbar2 = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup2, true);
|
||||
actionGroup2.add(new DefaultCustomComponentAction(myMatchInfoLabel));
|
||||
actionGroup2.add(new DefaultCustomComponentAction(myClickToHighlightLabel));
|
||||
|
||||
mySearchActionsToolbar1.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);
|
||||
mySearchActionsToolbar2.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);
|
||||
mySearchActionsToolbar1.setBorder(null);
|
||||
mySearchActionsToolbar2.setBorder(null);
|
||||
mySearchActionsToolbar1.setOpaque(false);
|
||||
mySearchActionsToolbar2.setOpaque(false);
|
||||
|
||||
new ShowMoreOptions(mySearchActionsToolbar1, mySearchFieldWrapper);
|
||||
Utils.setSmallerFontForChildren(mySearchActionsToolbar1);
|
||||
Utils.setSmallerFontForChildren(mySearchActionsToolbar2);
|
||||
}
|
||||
|
||||
private void initReplaceToolBars() {
|
||||
DefaultActionGroup actionGroup1 = new DefaultActionGroup("replace bar 1", false);
|
||||
myReplaceActionsToolbar1 = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup1, true);
|
||||
myReplaceActionsToolbar1.setForceMinimumSize(true);
|
||||
myReplaceActionsToolbar1.setReservePlaceAutoPopupIcon(false);
|
||||
final JButton myReplaceButton = new JButton("Replace");
|
||||
myReplaceButton.setFocusable(false);
|
||||
myReplaceButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
replaceCurrent();
|
||||
}
|
||||
});
|
||||
|
||||
final JButton myReplaceAllButton = new JButton("Replace all");
|
||||
myReplaceAllButton.setFocusable(false);
|
||||
myReplaceAllButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
myLivePreviewController.performReplaceAll();
|
||||
}
|
||||
});
|
||||
|
||||
final JButton myExcludeButton = new JButton("");
|
||||
myExcludeButton.setFocusable(false);
|
||||
myExcludeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
myLivePreviewController.exclude();
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
}
|
||||
});
|
||||
|
||||
if (!UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
|
||||
myReplaceButton.setMnemonic('p');
|
||||
myReplaceAllButton.setMnemonic('a');
|
||||
myExcludeButton.setMnemonic('l');
|
||||
}
|
||||
|
||||
actionGroup1.addAction(new DefaultCustomComponentAction(myReplaceButton){
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
myReplaceButton.setEnabled(canReplaceCurrent());
|
||||
}
|
||||
});
|
||||
actionGroup1.addAction(new DefaultCustomComponentAction(myReplaceAllButton) {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
myReplaceAllButton.setEnabled(mySearchResults != null && mySearchResults.hasMatches());
|
||||
}
|
||||
});
|
||||
actionGroup1.addAction(new DefaultCustomComponentAction(myExcludeButton) {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
FindResult cursor = mySearchResults != null ? mySearchResults.getCursor() : null;
|
||||
myExcludeButton.setEnabled(cursor != null);
|
||||
myExcludeButton.setText(cursor != null && mySearchResults.isExcluded(cursor) ? "Include" : "Exclude");
|
||||
}
|
||||
});
|
||||
|
||||
myReplaceActionsToolbar1.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);
|
||||
myReplaceActionsToolbar1.setBorder(null);
|
||||
myReplaceActionsToolbar1.setOpaque(false);
|
||||
DefaultActionGroup actionGroup2 = new DefaultActionGroup("replace bar 2", false);
|
||||
myReplaceActionsToolbar2 = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, actionGroup2, true);
|
||||
actionGroup2.addAction(new TogglePreserveCaseAction(this));
|
||||
actionGroup2.addAction(new ToggleSelectionOnlyAction(this));
|
||||
myReplaceActionsToolbar2.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);
|
||||
myReplaceActionsToolbar2.setBorder(null);
|
||||
myReplaceActionsToolbar2.setOpaque(false);
|
||||
Utils.setSmallerFontForChildren(myReplaceActionsToolbar1);
|
||||
Utils.setSmallerFontForChildren(myReplaceActionsToolbar2);
|
||||
}
|
||||
|
||||
private static void adjustRows(JTextArea area) {
|
||||
area.setRows(Math.max(2, Math.min(3, StringUtil.countChars(area.getText(),'\n')+1)));
|
||||
}
|
||||
|
||||
public FindModel getFindModel() {
|
||||
return myFindModel;
|
||||
}
|
||||
|
||||
private static void syncFindModels(FindModel to, FindModel from) {
|
||||
to.setCaseSensitive(from.isCaseSensitive());
|
||||
to.setWholeWordsOnly(from.isWholeWordsOnly());
|
||||
to.setRegularExpressions(from.isRegularExpressions());
|
||||
to.setSearchContext(from.getSearchContext());
|
||||
if (from.isReplaceState()) {
|
||||
to.setPreserveCase(from.isPreserveCase());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUIWithFindModel() {
|
||||
boolean needToResetSearchFocus = mySearchTextComponent.hasFocus();
|
||||
boolean needToResetReplaceFocus = myReplaceTextComponent.hasFocus();
|
||||
updateSearchComponent();
|
||||
updateReplaceComponent();
|
||||
if (myFindModel.isReplaceState()) {
|
||||
if (myReplaceFieldWrapper.getParent() == null) {
|
||||
myLeftPanel.add(myReplaceFieldWrapper, BorderLayout.CENTER);
|
||||
}
|
||||
if (myReplaceToolbarWrapper.getParent() == null) {
|
||||
myRightPanel.add(myReplaceToolbarWrapper, BorderLayout.CENTER);
|
||||
}
|
||||
if (needToResetReplaceFocus) {
|
||||
myReplaceTextComponent.requestFocusInWindow();
|
||||
}
|
||||
} else {
|
||||
if (myReplaceFieldWrapper.getParent() != null) {
|
||||
myLeftPanel.remove(myReplaceFieldWrapper);
|
||||
}
|
||||
if (myReplaceToolbarWrapper.getParent() != null) {
|
||||
myRightPanel.remove(myReplaceToolbarWrapper);
|
||||
}
|
||||
}
|
||||
if (needToResetSearchFocus) mySearchTextComponent.requestFocusInWindow();
|
||||
mySearchActionsToolbar1.updateActionsImmediately();
|
||||
mySearchActionsToolbar2.updateActionsImmediately();
|
||||
myReplaceActionsToolbar1.updateActionsImmediately();
|
||||
myReplaceActionsToolbar2.updateActionsImmediately();
|
||||
myReplaceToolbarWrapper.revalidate();
|
||||
revalidate();
|
||||
repaint();
|
||||
|
||||
myLivePreviewController.setTrackingSelection(!myFindModel.isGlobal());
|
||||
|
||||
}
|
||||
|
||||
private static boolean wholeWordsApplicable(String stringToFind) {
|
||||
return !stringToFind.startsWith(" ") &&
|
||||
!stringToFind.startsWith("\t") &&
|
||||
!stringToFind.endsWith(" ") &&
|
||||
!stringToFind.endsWith("\t");
|
||||
}
|
||||
|
||||
private void setMatchesLimit(int value) {
|
||||
mySearchResults.setMatchesLimit(value);
|
||||
}
|
||||
|
||||
private boolean canReplaceCurrent() {
|
||||
return myLivePreviewController != null && myLivePreviewController.canReplace();
|
||||
}
|
||||
|
||||
public void replaceCurrent() {
|
||||
if (mySearchResults.getCursor() != null) {
|
||||
myLivePreviewController.performReplace();
|
||||
}
|
||||
}
|
||||
|
||||
public void showHistory(final boolean byClickingToolbarButton, JTextComponent textField) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("find.recent.search");
|
||||
FindSettings settings = FindSettings.getInstance();
|
||||
String[] recent = textField == mySearchTextComponent ? settings.getRecentFindStrings() : settings.getRecentReplaceStrings();
|
||||
final boolean toShowAd = textField == mySearchTextComponent && textField.getText().isEmpty() && FindManager.getInstance(myProject).getPreviousFindModel() != null;
|
||||
Utils.showCompletionPopup(byClickingToolbarButton ? mySearchActionsToolbar1 : null,
|
||||
new JBList((Object[])ArrayUtil.reverseArray(recent)),
|
||||
"Recent " + (textField == mySearchTextComponent ? "Searches" : "Replaces"),
|
||||
textField,
|
||||
toShowAd ? RestorePreviousSettingsAction.getAd() : null);
|
||||
}
|
||||
|
||||
private boolean updateTextComponent(final boolean search) {
|
||||
JTextComponent oldComponent = search ? mySearchTextComponent : myReplaceTextComponent;
|
||||
Color oldBackground = oldComponent != null ? oldComponent.getBackground() : null;
|
||||
Wrapper wrapper = search ? mySearchFieldWrapper : myReplaceFieldWrapper;
|
||||
boolean multiline = myFindModel.isMultiline();
|
||||
if (multiline && oldComponent instanceof JTextArea) return false;
|
||||
if (!multiline && oldComponent instanceof JTextField) return false;
|
||||
|
||||
final JTextComponent textComponent;
|
||||
if (multiline) {
|
||||
textComponent = new JTextArea();
|
||||
((JTextArea)textComponent).setColumns(25);
|
||||
((JTextArea)textComponent).setRows(2);
|
||||
wrapper.setContent(new SearchWrapper(textComponent, new ShowHistoryAction(textComponent, this)));
|
||||
}
|
||||
else {
|
||||
SearchTextField searchTextField = new SearchTextField(true);
|
||||
searchTextField.setOpaque(false);
|
||||
textComponent = searchTextField.getTextEditor();
|
||||
searchTextField.getTextEditor().setColumns(25);
|
||||
if (UIUtil.isUnderGTKLookAndFeel()) {
|
||||
textComponent.setOpaque(false);
|
||||
}
|
||||
searchTextField.setHistorySize(20);
|
||||
searchTextField.setHistory(ContainerUtil.reverse(Arrays.asList(search
|
||||
? FindSettings.getInstance().getRecentFindStrings()
|
||||
: FindSettings.getInstance().getRecentReplaceStrings())));
|
||||
textComponent.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final String text = textComponent.getText();
|
||||
myFindModel.setMultiline(true);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (search) {
|
||||
mySearchTextComponent.setText(text+"\n");
|
||||
} else {
|
||||
myReplaceTextComponent.setText(text+"\n");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_DOWN_MASK), JComponent.WHEN_FOCUSED);
|
||||
wrapper.setContent(searchTextField);
|
||||
}
|
||||
|
||||
if (search) {
|
||||
mySearchTextComponent = textComponent;
|
||||
} else {
|
||||
myReplaceTextComponent = textComponent;
|
||||
}
|
||||
|
||||
UIUtil.addUndoRedoActions(textComponent);
|
||||
Utils.setSmallerFont(textComponent);
|
||||
|
||||
textComponent.putClientProperty("AuxEditorComponent", Boolean.TRUE);
|
||||
if (oldBackground != null) {
|
||||
textComponent.setBackground(oldBackground);
|
||||
}
|
||||
textComponent.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(final FocusEvent e) {
|
||||
textComponent.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(final FocusEvent e) {
|
||||
textComponent.repaint();
|
||||
}
|
||||
});
|
||||
new CloseOnESCAction(this, textComponent);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void requestFocus(Component c) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(c, true);
|
||||
}
|
||||
|
||||
public void searchBackward() {
|
||||
moveCursor(SearchResults.Direction.UP);
|
||||
addTextToRecent(mySearchTextComponent);
|
||||
}
|
||||
|
||||
public void searchForward() {
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
addTextToRecent(mySearchTextComponent);
|
||||
}
|
||||
|
||||
public void addTextToRecent(JTextComponent textField) {
|
||||
final String text = textField.getText();
|
||||
if (text.length() > 0) {
|
||||
if (textField == mySearchTextComponent) {
|
||||
FindSettings.getInstance().addStringToFind(text);
|
||||
if (mySearchFieldWrapper.getTargetComponent() instanceof SearchTextField) {
|
||||
((SearchTextField)mySearchFieldWrapper.getTargetComponent()).addCurrentTextToHistory();
|
||||
}
|
||||
} else {
|
||||
FindSettings.getInstance().addStringToReplace(text);
|
||||
if (myReplaceFieldWrapper.getTargetComponent() instanceof SearchTextField) {
|
||||
((SearchTextField)myReplaceFieldWrapper.getTargetComponent()).addCurrentTextToHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(SelectionEvent e) {
|
||||
updateResults(false);
|
||||
}
|
||||
|
||||
private void moveCursor(SearchResults.Direction direction) {
|
||||
myLivePreviewController.moveCursor(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
mySearchTextComponent.setSelectionStart(0);
|
||||
mySearchTextComponent.setSelectionEnd(mySearchTextComponent.getText().length());
|
||||
requestFocus(mySearchTextComponent);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), false);
|
||||
|
||||
myLivePreviewController.dispose();
|
||||
myEditor.setHeaderComponent(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
initLivePreview();
|
||||
}
|
||||
|
||||
private void initLivePreview() {
|
||||
myLivePreviewController.on();
|
||||
|
||||
myLivePreviewController.setUserActivityDelay(0);
|
||||
updateResults(false);
|
||||
myLivePreviewController.setUserActivityDelay(LivePreviewController.USER_ACTIVITY_TRIGGERING_DELAY);
|
||||
|
||||
mySearchResults.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
myLivePreviewController.off();
|
||||
mySearchResults.removeListener(this);
|
||||
|
||||
addTextToRecent(mySearchTextComponent);
|
||||
if (myReplaceTextComponent != null) {
|
||||
addTextToRecent(myReplaceTextComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateResults(final boolean allowedToChangedEditorSelection) {
|
||||
final String text = myFindModel.getStringToFind();
|
||||
if (text.length() == 0) {
|
||||
nothingToSearchFor();
|
||||
}
|
||||
else {
|
||||
|
||||
if (myFindModel.isRegularExpressions()) {
|
||||
try {
|
||||
Pattern.compile(text);
|
||||
}
|
||||
catch (Exception e) {
|
||||
setNotFoundBackground();
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
mySearchResults.clear();
|
||||
myMatchInfoLabel.setText("Incorrect regular expression");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final FindManager findManager = FindManager.getInstance(myProject);
|
||||
if (allowedToChangedEditorSelection) {
|
||||
findManager.setFindWasPerformed();
|
||||
FindModel copy = new FindModel();
|
||||
copy.copyFrom(myFindModel);
|
||||
copy.setReplaceState(false);
|
||||
findManager.setFindNextModel(copy);
|
||||
}
|
||||
if (myLivePreviewController != null) {
|
||||
myLivePreviewController.updateInBackground(myFindModel, allowedToChangedEditorSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void nothingToSearchFor() {
|
||||
updateUIWithEmptyResults();
|
||||
if (mySearchResults != null) {
|
||||
mySearchResults.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUIWithEmptyResults() {
|
||||
setRegularBackground();
|
||||
myMatchInfoLabel.setText("");
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
}
|
||||
|
||||
private void setRegularBackground() {
|
||||
mySearchTextComponent.setBackground(myDefaultBackground);
|
||||
}
|
||||
|
||||
private void setNotFoundBackground() {
|
||||
mySearchTextComponent.setBackground(LightColors.RED);
|
||||
}
|
||||
|
||||
public String getTextInField() {
|
||||
return mySearchTextComponent.getText();
|
||||
}
|
||||
|
||||
public void setTextInField(final String text) {
|
||||
mySearchTextComponent.setText(text);
|
||||
myFindModel.setStringToFind(text);
|
||||
}
|
||||
|
||||
public boolean hasMatches() {
|
||||
return mySearchResults != null && mySearchResults.hasMatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getInsets() {
|
||||
Insets insets = super.getInsets();
|
||||
if (UIUtil.isUnderGTKLookAndFeel() || UIUtil.isUnderNimbusLookAndFeel()) {
|
||||
insets.top += 1;
|
||||
insets.bottom += 2;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
public void selectAllOccurrences() {
|
||||
FindUtil.selectSearchResultsInEditor(myEditor, mySearchResults.getOccurrences().iterator(), -1);
|
||||
}
|
||||
|
||||
public void removeOccurrence() {
|
||||
mySearchResults.prevOccurrence(true);
|
||||
}
|
||||
|
||||
public void addNextOccurrence() {
|
||||
mySearchResults.nextOccurrence(true);
|
||||
}
|
||||
|
||||
public void clearUndoInTextFields() {
|
||||
UIUtil.resetUndoRedoActions(mySearchTextComponent);
|
||||
UIUtil.resetUndoRedoActions(myReplaceTextComponent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.find;
|
||||
|
||||
import com.intellij.find.editorHeaderActions.*;
|
||||
import com.intellij.find.impl.livePreview.LivePreviewController;
|
||||
import com.intellij.find.impl.livePreview.SearchResults;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
|
||||
import com.intellij.openapi.actionSystem.ex.DefaultCustomComponentAction;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.event.SelectionEvent;
|
||||
import com.intellij.openapi.editor.event.SelectionListener;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.BooleanGetter;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.components.labels.LinkLabel;
|
||||
import com.intellij.ui.components.labels.LinkListener;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ui.update.Activatable;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author max, andrey.zaytsev
|
||||
*/
|
||||
public class EditorSearchSession implements DataProvider,
|
||||
SelectionListener,
|
||||
SearchResults.SearchResultsListener,
|
||||
SearchReplaceComponent.Listener {
|
||||
public static DataKey<EditorSearchSession> SESSION_KEY = DataKey.create("EditorSearchSession");
|
||||
|
||||
private final Editor myEditor;
|
||||
private final LivePreviewController myLivePreviewController;
|
||||
private final SearchResults mySearchResults;
|
||||
private final FindModel myFindModel;
|
||||
private final SearchReplaceComponent myComponent;
|
||||
|
||||
private final LinkLabel<Object> myClickToHighlightLabel = new LinkLabel<Object>("Click to highlight", null, new LinkListener<Object>() {
|
||||
@Override
|
||||
public void linkSelected(LinkLabel aSource, Object aLinkData) {
|
||||
setMatchesLimit(Integer.MAX_VALUE);
|
||||
updateResults(true);
|
||||
}
|
||||
});
|
||||
|
||||
public EditorSearchSession(@NotNull Editor editor, Project project) {
|
||||
this(editor, project, createDefaultFindModel(project, editor));
|
||||
}
|
||||
|
||||
public EditorSearchSession(@NotNull final Editor editor, Project project, FindModel findModel) {
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
|
||||
myFindModel = findModel;
|
||||
|
||||
myEditor = editor;
|
||||
|
||||
mySearchResults = new SearchResults(myEditor, project);
|
||||
myLivePreviewController = new LivePreviewController(mySearchResults, this);
|
||||
|
||||
myComponent = SearchReplaceComponent
|
||||
.buildFor(project, myEditor.getContentComponent())
|
||||
.addPrimarySearchActions(createPrevOccurrenceAction(),
|
||||
createNextOccurrenceAction(),
|
||||
new FindAllAction(),
|
||||
new Separator(),
|
||||
new AddOccurrenceAction(),
|
||||
new RemoveOccurrenceAction(),
|
||||
new SelectAllAction(),
|
||||
new Separator())
|
||||
.addSecondarySearchActions(new ToggleInCommentsAction(),
|
||||
new ToggleInLiteralsOnlyAction(),
|
||||
new ToggleExceptCommentsAction(),
|
||||
new ToggleExceptLiteralsAction(),
|
||||
new ToggleExceptCommentsAndLiteralsAction())
|
||||
.addExtraSearchActions(new ToggleMatchCase(),
|
||||
new ToggleRegex(),
|
||||
new ToggleWholeWordsOnlyAction(),
|
||||
new StatusTextAction(),
|
||||
new DefaultCustomComponentAction(myClickToHighlightLabel))
|
||||
.addSearchFieldActions(new RestorePreviousSettingsAction())
|
||||
.addPrimaryReplaceActions(new ReplaceAction(),
|
||||
new ReplaceAllAction(),
|
||||
new ExcludeAction())
|
||||
.addExtraReplaceAction(new TogglePreserveCaseAction(),
|
||||
new ToggleSelectionOnlyAction())
|
||||
.addReplaceFieldActions(createPrevOccurrenceAction(),
|
||||
createNextOccurrenceAction())
|
||||
.withDataProvider(this)
|
||||
.withCloseAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
close();
|
||||
}
|
||||
})
|
||||
.withReplaceAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
replaceCurrent();
|
||||
}
|
||||
})
|
||||
.withSecondarySearchActionsIsModifiedGetter(new BooleanGetter() {
|
||||
@Override
|
||||
public boolean get() {
|
||||
return myFindModel.getSearchContext() != FindModel.SearchContext.ANY;
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
myComponent.addListener(this);
|
||||
new UiNotifyConnector(myComponent, new Activatable() {
|
||||
@Override
|
||||
public void showNotify() {
|
||||
initLivePreview();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideNotify() {
|
||||
myLivePreviewController.off();
|
||||
mySearchResults.removeListener(EditorSearchSession.this);
|
||||
}
|
||||
});
|
||||
|
||||
new SwitchToFind(getComponent());
|
||||
new SwitchToReplace(getComponent());
|
||||
|
||||
myFindModel.addObserver(new FindModel.FindModelObserver() {
|
||||
@Override
|
||||
public void findModelChanged(FindModel findModel) {
|
||||
String stringToFind = myFindModel.getStringToFind();
|
||||
if (!wholeWordsApplicable(stringToFind)) {
|
||||
myFindModel.setWholeWordsOnly(false);
|
||||
}
|
||||
updateUIWithFindModel();
|
||||
updateResults(true);
|
||||
syncFindModels(FindManager.getInstance(getProject()).getFindInFileModel(), myFindModel);
|
||||
}
|
||||
});
|
||||
|
||||
updateUIWithFindModel();
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
initLivePreview();
|
||||
}
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static EditorSearchSession get(@Nullable Editor editor) {
|
||||
JComponent headerComponent = editor != null ? editor.getHeaderComponent() : null;
|
||||
SearchReplaceComponent searchReplaceComponent = ObjectUtils.tryCast(headerComponent, SearchReplaceComponent.class);
|
||||
return searchReplaceComponent != null ? SESSION_KEY.getData(searchReplaceComponent) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EditorSearchSession start(@NotNull Editor editor, @Nullable Project project) {
|
||||
EditorSearchSession session = new EditorSearchSession(editor, project);
|
||||
editor.setHeaderComponent(session.getComponent());
|
||||
return session;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EditorSearchSession start(@NotNull Editor editor, @NotNull FindModel findModel, @Nullable Project project) {
|
||||
EditorSearchSession session = new EditorSearchSession(editor, project, findModel);
|
||||
editor.setHeaderComponent(session.getComponent());
|
||||
return session;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SearchReplaceComponent getComponent() {
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myComponent.getProject();
|
||||
}
|
||||
|
||||
private static FindModel createDefaultFindModel(Project project, Editor editor) {
|
||||
FindModel findModel = new FindModel();
|
||||
findModel.copyFrom(FindManager.getInstance(project).getFindInFileModel());
|
||||
if (editor.getSelectionModel().hasSelection()) {
|
||||
String selectedText = editor.getSelectionModel().getSelectedText();
|
||||
if (selectedText != null) {
|
||||
findModel.setStringToFind(selectedText);
|
||||
}
|
||||
}
|
||||
findModel.setPromptOnReplace(false);
|
||||
return findModel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getData(@NonNls final String dataId) {
|
||||
if (SESSION_KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
if (CommonDataKeys.EDITOR_EVEN_IF_INACTIVE.is(dataId)) {
|
||||
return myEditor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchResultsUpdated(SearchResults sr) {
|
||||
if (myComponent.getSearchTextComponent().getText().isEmpty()) {
|
||||
updateUIWithEmptyResults();
|
||||
} else {
|
||||
int matches = sr.getMatchesCount();
|
||||
boolean tooManyMatches = matches > mySearchResults.getMatchesLimit();
|
||||
myComponent.setStatusText(tooManyMatches
|
||||
? ApplicationBundle.message("editorsearch.toomuch", mySearchResults.getMatchesLimit())
|
||||
: ApplicationBundle.message("editorsearch.matches", matches));
|
||||
myClickToHighlightLabel.setVisible(tooManyMatches);
|
||||
if (!tooManyMatches && matches <= 0) {
|
||||
myComponent.setNotFoundBackground();
|
||||
}
|
||||
else {
|
||||
myComponent.setRegularBackground();
|
||||
}
|
||||
}
|
||||
myComponent.updateActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cursorMoved() {
|
||||
myComponent.updateActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchFieldDocumentChanged() {
|
||||
setMatchesLimit(LivePreviewController.MATCHES_LIMIT);
|
||||
String text = myComponent.getSearchTextComponent().getText();
|
||||
myFindModel.setStringToFind(text);
|
||||
if (!StringUtil.isEmpty(text)) {
|
||||
updateResults(true);
|
||||
}
|
||||
else {
|
||||
nothingToSearchFor();
|
||||
}
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
private void updateMultiLineStateIfNeed() {
|
||||
myFindModel.setMultiline(myComponent.getSearchTextComponent().getText().contains("\n") ||
|
||||
myComponent.getReplaceTextComponent().getText().contains("\n"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceFieldDocumentChanged() {
|
||||
setMatchesLimit(LivePreviewController.MATCHES_LIMIT);
|
||||
myFindModel.setStringToReplace(myComponent.getReplaceTextComponent().getText());
|
||||
updateMultiLineStateIfNeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multilineStateChanged() {
|
||||
myFindModel.setMultiline(myComponent.isMultiline());
|
||||
}
|
||||
|
||||
public FindModel getFindModel() {
|
||||
return myFindModel;
|
||||
}
|
||||
|
||||
private static void syncFindModels(FindModel to, FindModel from) {
|
||||
to.setCaseSensitive(from.isCaseSensitive());
|
||||
to.setWholeWordsOnly(from.isWholeWordsOnly());
|
||||
to.setRegularExpressions(from.isRegularExpressions());
|
||||
to.setSearchContext(from.getSearchContext());
|
||||
if (from.isReplaceState()) {
|
||||
to.setPreserveCase(from.isPreserveCase());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUIWithFindModel() {
|
||||
myComponent.update(myFindModel.getStringToFind(),
|
||||
myFindModel.getStringToReplace(),
|
||||
myFindModel.isReplaceState(),
|
||||
myFindModel.isMultiline());
|
||||
myLivePreviewController.setTrackingSelection(!myFindModel.isGlobal());
|
||||
}
|
||||
|
||||
private static boolean wholeWordsApplicable(String stringToFind) {
|
||||
return !stringToFind.startsWith(" ") &&
|
||||
!stringToFind.startsWith("\t") &&
|
||||
!stringToFind.endsWith(" ") &&
|
||||
!stringToFind.endsWith("\t");
|
||||
}
|
||||
|
||||
private void setMatchesLimit(int value) {
|
||||
mySearchResults.setMatchesLimit(value);
|
||||
}
|
||||
|
||||
private boolean canReplaceCurrent() {
|
||||
return myLivePreviewController != null && myLivePreviewController.canReplace();
|
||||
}
|
||||
|
||||
public void replaceCurrent() {
|
||||
if (mySearchResults.getCursor() != null) {
|
||||
myLivePreviewController.performReplace();
|
||||
}
|
||||
}
|
||||
|
||||
public void searchBackward() {
|
||||
moveCursor(SearchResults.Direction.UP);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
public void searchForward() {
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
public void addTextToRecent(JTextComponent textField) {
|
||||
myComponent.addTextToRecent(textField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(SelectionEvent e) {
|
||||
updateResults(false);
|
||||
}
|
||||
|
||||
private void moveCursor(SearchResults.Direction direction) {
|
||||
myLivePreviewController.moveCursor(direction);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
IdeFocusManager.getInstance(getProject()).requestFocus(myEditor.getContentComponent(), false);
|
||||
|
||||
myLivePreviewController.dispose();
|
||||
myEditor.setHeaderComponent(null);
|
||||
}
|
||||
|
||||
private void initLivePreview() {
|
||||
myLivePreviewController.on();
|
||||
|
||||
myLivePreviewController.setUserActivityDelay(0);
|
||||
updateResults(false);
|
||||
myLivePreviewController.setUserActivityDelay(LivePreviewController.USER_ACTIVITY_TRIGGERING_DELAY);
|
||||
|
||||
mySearchResults.addListener(this);
|
||||
}
|
||||
|
||||
private void updateResults(final boolean allowedToChangedEditorSelection) {
|
||||
final String text = myFindModel.getStringToFind();
|
||||
if (text.length() == 0) {
|
||||
nothingToSearchFor();
|
||||
}
|
||||
else {
|
||||
|
||||
if (myFindModel.isRegularExpressions()) {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
Pattern.compile(text);
|
||||
}
|
||||
catch (Exception e) {
|
||||
myComponent.setNotFoundBackground();
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
mySearchResults.clear();
|
||||
myComponent.setStatusText("Incorrect regular expression");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final FindManager findManager = FindManager.getInstance(getProject());
|
||||
if (allowedToChangedEditorSelection) {
|
||||
findManager.setFindWasPerformed();
|
||||
FindModel copy = new FindModel();
|
||||
copy.copyFrom(myFindModel);
|
||||
copy.setReplaceState(false);
|
||||
findManager.setFindNextModel(copy);
|
||||
}
|
||||
if (myLivePreviewController != null) {
|
||||
myLivePreviewController.updateInBackground(myFindModel, allowedToChangedEditorSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void nothingToSearchFor() {
|
||||
updateUIWithEmptyResults();
|
||||
if (mySearchResults != null) {
|
||||
mySearchResults.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUIWithEmptyResults() {
|
||||
myComponent.setRegularBackground();
|
||||
myComponent.setStatusText("");
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
}
|
||||
|
||||
public String getTextInField() {
|
||||
return myComponent.getSearchTextComponent().getText();
|
||||
}
|
||||
|
||||
public void setTextInField(final String text) {
|
||||
myComponent.getSearchTextComponent().setText(text);
|
||||
myFindModel.setStringToFind(text);
|
||||
}
|
||||
|
||||
public boolean hasMatches() {
|
||||
return mySearchResults != null && mySearchResults.hasMatches();
|
||||
}
|
||||
|
||||
public void selectAllOccurrences() {
|
||||
FindUtil.selectSearchResultsInEditor(myEditor, mySearchResults.getOccurrences().iterator(), -1);
|
||||
}
|
||||
|
||||
public void removeOccurrence() {
|
||||
mySearchResults.prevOccurrence(true);
|
||||
}
|
||||
|
||||
public void addNextOccurrence() {
|
||||
mySearchResults.nextOccurrence(true);
|
||||
}
|
||||
|
||||
public void clearUndoInTextFields() {
|
||||
myComponent.resetUndoRedoActions();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
static NextOccurrenceAction createNextOccurrenceAction() {
|
||||
return new NextOccurrenceAction(new PrevNextActionHandler() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SESSION_KEY).searchForward();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static PrevOccurrenceAction createPrevOccurrenceAction() {
|
||||
return new PrevOccurrenceAction(new PrevNextActionHandler() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SESSION_KEY).searchBackward();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static abstract class ButtonAction extends DumbAwareAction implements CustomComponentAction, ActionListener {
|
||||
private final String myTitle;
|
||||
private final char myMnemonic;
|
||||
|
||||
protected ButtonAction(@NotNull String title, char mnemonic) {
|
||||
myTitle = title;
|
||||
myMnemonic = mnemonic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createCustomComponent(Presentation presentation) {
|
||||
JButton button = new JButton(myTitle);
|
||||
button.setFocusable(false);
|
||||
if (!UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
|
||||
button.setMnemonic(myMnemonic);
|
||||
}
|
||||
button.addActionListener(this);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void update(AnActionEvent e) {
|
||||
JButton button = (JButton)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY);
|
||||
if (button != null) {
|
||||
update(button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void actionPerformed(AnActionEvent e) {
|
||||
onClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void actionPerformed(ActionEvent e) {
|
||||
onClick();
|
||||
}
|
||||
|
||||
protected abstract void update(@NotNull JButton button);
|
||||
|
||||
protected abstract void onClick();
|
||||
}
|
||||
|
||||
private class ReplaceAction extends ButtonAction {
|
||||
public ReplaceAction() {
|
||||
super("Replace", 'p');
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(@NotNull JButton button) {
|
||||
button.setEnabled(mySearchResults.hasMatches());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
replaceCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
private class ReplaceAllAction extends ButtonAction {
|
||||
public ReplaceAllAction() {
|
||||
super("Replace all", 'a');
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(@NotNull JButton button) {
|
||||
button.setEnabled(mySearchResults.hasMatches());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
myLivePreviewController.performReplaceAll();
|
||||
}
|
||||
}
|
||||
|
||||
private class ExcludeAction extends ButtonAction {
|
||||
public ExcludeAction() {
|
||||
super("", 'l');
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(@NotNull JButton button) {
|
||||
FindResult cursor = mySearchResults.getCursor();
|
||||
button.setEnabled(cursor != null);
|
||||
button.setText(cursor != null && mySearchResults.isExcluded(cursor) ? "Include" : "Exclude");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
myLivePreviewController.exclude();
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class PrevNextActionHandler implements PrevNextOccurrenceAction.Handler {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
EditorSearchSession search = e.getData(SESSION_KEY);
|
||||
e.getPresentation().setEnabled(search != null && search.hasMatches());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,10 +192,9 @@ public class FindUtil {
|
||||
model.setCaseSensitive(true);
|
||||
model.setWholeWordsOnly(!editor.getSelectionModel().hasSelection());
|
||||
|
||||
final JComponent header = editor.getHeaderComponent();
|
||||
if (header instanceof EditorSearchComponent) {
|
||||
final EditorSearchComponent searchComponent = (EditorSearchComponent)header;
|
||||
searchComponent.setTextInField(model.getStringToFind());
|
||||
EditorSearchSession searchSession = EditorSearchSession.get(editor);
|
||||
if (searchSession != null) {
|
||||
searchSession.setTextInField(model.getStringToFind());
|
||||
}
|
||||
|
||||
findManager.setFindNextModel(model);
|
||||
|
||||
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find;
|
||||
|
||||
import com.intellij.find.editorHeaderActions.ContextAwareShortcutProvider;
|
||||
import com.intellij.find.editorHeaderActions.ShowMoreOptions;
|
||||
import com.intellij.find.editorHeaderActions.Utils;
|
||||
import com.intellij.find.editorHeaderActions.VariantsCompletionAction;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.impl.EditorHeaderComponent;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.BooleanGetter;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.LightColors;
|
||||
import com.intellij.ui.OnePixelSplitter;
|
||||
import com.intellij.ui.SearchTextField;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchSupply;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchReplaceComponent extends EditorHeaderComponent implements DataProvider {
|
||||
public static final DataKey<SearchReplaceComponent> COMPONENT_KEY = DataKey.create("search-replace-component");
|
||||
public static final DataKey<String> STATUS_TEXT_KEY = DataKey.create("search-replace-status-text");
|
||||
|
||||
private final EventDispatcher<Listener> myEventDispatcher = EventDispatcher.create(Listener.class);
|
||||
|
||||
private final MyTextComponentWrapper mySearchFieldWrapper;
|
||||
private JTextComponent mySearchTextComponent;
|
||||
|
||||
private final MyTextComponentWrapper myReplaceFieldWrapper;
|
||||
private JTextComponent myReplaceTextComponent;
|
||||
|
||||
private final JPanel myLeftPanel;
|
||||
private final JPanel myRightPanel;
|
||||
|
||||
private final DefaultActionGroup mySearchFieldActions;
|
||||
private final ActionToolbarImpl mySearchActionsToolbar1;
|
||||
private final ActionToolbarImpl mySearchActionsToolbar2;
|
||||
private final ActionToolbarImpl.PopupStateModifier mySearchToolbar1PopupStateModifier;
|
||||
|
||||
private final DefaultActionGroup myReplaceFieldActions;
|
||||
private final ActionToolbarImpl myReplaceActionsToolbar1;
|
||||
private final ActionToolbarImpl myReplaceActionsToolbar2;
|
||||
private final JPanel myReplaceToolbarWrapper;
|
||||
|
||||
private final Project myProject;
|
||||
private final JComponent myTargetComponent;
|
||||
|
||||
private final Runnable myCloseAction;
|
||||
private final Runnable myReplaceAction;
|
||||
|
||||
private final DataProvider myDataProviderDelegate;
|
||||
|
||||
private boolean myMultilineMode;
|
||||
private String myStatusText;
|
||||
|
||||
@NotNull
|
||||
public static Builder buildFor(@Nullable Project project, @NotNull JComponent component) {
|
||||
return new Builder(project, component);
|
||||
}
|
||||
|
||||
private SearchReplaceComponent(@Nullable Project project,
|
||||
@NotNull JComponent targetComponent,
|
||||
@NotNull DefaultActionGroup searchToolbar1Actions,
|
||||
@NotNull final BooleanGetter searchToolbar1ModifiedFlagGetter,
|
||||
@NotNull DefaultActionGroup searchToolbar2Actions,
|
||||
@NotNull DefaultActionGroup searchFieldActions,
|
||||
@NotNull DefaultActionGroup replaceToolbar1Actions,
|
||||
@NotNull DefaultActionGroup replaceToolbar2Actions,
|
||||
@NotNull DefaultActionGroup replaceFieldActions,
|
||||
@Nullable Runnable replaceAction,
|
||||
@Nullable Runnable closeAction,
|
||||
@Nullable DataProvider dataProvider) {
|
||||
myProject = project;
|
||||
myTargetComponent = targetComponent;
|
||||
mySearchFieldActions = searchFieldActions;
|
||||
myReplaceFieldActions = replaceFieldActions;
|
||||
myReplaceAction = replaceAction;
|
||||
myCloseAction = closeAction;
|
||||
|
||||
mySearchToolbar1PopupStateModifier = new ActionToolbarImpl.PopupStateModifier() {
|
||||
@Override
|
||||
public int getModifiedPopupState() {
|
||||
return ActionButtonComponent.PUSHED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willModify() {
|
||||
return searchToolbar1ModifiedFlagGetter.get();
|
||||
}
|
||||
};
|
||||
|
||||
mySearchFieldWrapper = new MyTextComponentWrapper() {
|
||||
@Override
|
||||
public void setContent(JComponent wrapped) {
|
||||
super.setContent(wrapped);
|
||||
mySearchTextComponent = unwrapTextComponent(wrapped);
|
||||
}
|
||||
};
|
||||
myReplaceFieldWrapper = new MyTextComponentWrapper() {
|
||||
@Override
|
||||
public void setContent(JComponent wrapped) {
|
||||
super.setContent(wrapped);
|
||||
myReplaceTextComponent = unwrapTextComponent(wrapped);
|
||||
}
|
||||
};
|
||||
|
||||
myLeftPanel = new NonOpaquePanel(new BorderLayout());
|
||||
myLeftPanel.add(mySearchFieldWrapper, BorderLayout.NORTH);
|
||||
myLeftPanel.add(myReplaceFieldWrapper, BorderLayout.CENTER);
|
||||
|
||||
mySearchActionsToolbar1 = createSearchToolbar1(searchToolbar1Actions);
|
||||
Wrapper searchToolbarWrapper1 = new NonOpaquePanel(new BorderLayout());
|
||||
searchToolbarWrapper1.add(mySearchActionsToolbar1, BorderLayout.WEST);
|
||||
mySearchActionsToolbar2 = createSearchToolbar2(searchToolbar2Actions);
|
||||
Wrapper searchToolbarWrapper2 = new Wrapper(mySearchActionsToolbar2);
|
||||
mySearchActionsToolbar2.setBorder(JBUI.Borders.emptyLeft(16));
|
||||
JPanel searchPair = new NonOpaquePanel(new BorderLayout()).setVerticalSizeReferent(mySearchFieldWrapper);
|
||||
searchPair.add(searchToolbarWrapper1, BorderLayout.WEST);
|
||||
searchPair.add(searchToolbarWrapper2, BorderLayout.CENTER);
|
||||
|
||||
myReplaceActionsToolbar1 = createReplaceToolbar1(replaceToolbar1Actions);
|
||||
Wrapper replaceToolbarWrapper1 = new Wrapper(myReplaceActionsToolbar1).setVerticalSizeReferent(myReplaceFieldWrapper);
|
||||
myReplaceActionsToolbar2 = createReplaceToolbar2(replaceToolbar2Actions);
|
||||
Wrapper replaceToolbarWrapper2 = new Wrapper(myReplaceActionsToolbar2).setVerticalSizeReferent(myReplaceFieldWrapper);
|
||||
myReplaceActionsToolbar2.setBorder(JBUI.Borders.emptyLeft(16));
|
||||
myReplaceToolbarWrapper = new NonOpaquePanel(new BorderLayout());
|
||||
myReplaceToolbarWrapper.add(replaceToolbarWrapper1, BorderLayout.WEST);
|
||||
myReplaceToolbarWrapper.add(replaceToolbarWrapper2, BorderLayout.CENTER);
|
||||
|
||||
searchToolbarWrapper1.setHorizontalSizeReferent(replaceToolbarWrapper1);
|
||||
|
||||
JLabel closeLabel = new JLabel(null, AllIcons.Actions.Cross, SwingConstants.RIGHT);
|
||||
closeLabel.setBorder(JBUI.Borders.empty(5));
|
||||
closeLabel.setVerticalAlignment(SwingConstants.TOP);
|
||||
closeLabel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
closeLabel.setToolTipText("Close search bar (Escape)");
|
||||
searchPair.add(new Wrapper.North(closeLabel), BorderLayout.EAST);
|
||||
|
||||
myRightPanel = new NonOpaquePanel(new BorderLayout());
|
||||
myRightPanel.add(searchPair, BorderLayout.NORTH);
|
||||
myRightPanel.add(myReplaceToolbarWrapper, BorderLayout.CENTER);
|
||||
|
||||
OnePixelSplitter splitter = new OnePixelSplitter(false, .25F);
|
||||
splitter.setFirstComponent(myLeftPanel);
|
||||
splitter.setSecondComponent(myRightPanel);
|
||||
splitter.setHonorComponentsMinimumSize(true);
|
||||
splitter.setAndLoadSplitterProportionKey("FindSplitterProportion");
|
||||
splitter.setOpaque(false);
|
||||
splitter.getDivider().setOpaque(false);
|
||||
add(splitter, BorderLayout.CENTER);
|
||||
|
||||
update("", "", false, false);
|
||||
|
||||
// it's assigned after all action updates so that actions don't get access to uninitialized components
|
||||
myDataProviderDelegate = dataProvider;
|
||||
}
|
||||
|
||||
public void resetUndoRedoActions() {
|
||||
UIUtil.resetUndoRedoActions(mySearchTextComponent);
|
||||
UIUtil.resetUndoRedoActions(myReplaceTextComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
|
||||
addTextToRecent(mySearchTextComponent);
|
||||
if (myReplaceTextComponent != null) {
|
||||
addTextToRecent(myReplaceTextComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
mySearchTextComponent.setSelectionStart(0);
|
||||
mySearchTextComponent.setSelectionEnd(mySearchTextComponent.getText().length());
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(mySearchTextComponent, true);
|
||||
}
|
||||
|
||||
public void setStatusText(@NotNull String status) {
|
||||
myStatusText = status;
|
||||
}
|
||||
|
||||
public void replace() {
|
||||
if (myReplaceAction != null) {
|
||||
myReplaceAction.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (myCloseAction != null ) {
|
||||
myCloseAction.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRegularBackground() {
|
||||
mySearchTextComponent.setBackground(UIUtil.getTextFieldBackground());
|
||||
}
|
||||
|
||||
public void setNotFoundBackground() {
|
||||
mySearchTextComponent.setBackground(LightColors.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getInsets() {
|
||||
Insets insets = super.getInsets();
|
||||
if (UIUtil.isUnderGTKLookAndFeel() || UIUtil.isUnderNimbusLookAndFeel()) {
|
||||
insets.top += 1;
|
||||
insets.bottom += 2;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (STATUS_TEXT_KEY.is(dataId)) {
|
||||
return myStatusText;
|
||||
}
|
||||
if (COMPONENT_KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
if (SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.is(dataId)) {
|
||||
return mySearchTextComponent.getText();
|
||||
}
|
||||
return myDataProviderDelegate != null ? myDataProviderDelegate.getData(dataId) : null;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
public void addListener(@NotNull Listener listener) {
|
||||
myEventDispatcher.addListener(listener);
|
||||
}
|
||||
|
||||
public boolean isMultiline() {
|
||||
return myMultilineMode;
|
||||
}
|
||||
|
||||
private void setMultilineInternal(boolean multiline) {
|
||||
boolean stateChanged = multiline != myMultilineMode;
|
||||
myMultilineMode = multiline;
|
||||
if (stateChanged) {
|
||||
multilineStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JTextComponent getSearchTextComponent() {
|
||||
return mySearchTextComponent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JTextComponent getReplaceTextComponent() {
|
||||
return myReplaceTextComponent;
|
||||
}
|
||||
|
||||
|
||||
private void updateSearchComponent(@NotNull String textToSet) {
|
||||
final int oldCaretPosition = mySearchTextComponent != null ? mySearchTextComponent.getCaretPosition() : 0;
|
||||
boolean wasNull = mySearchTextComponent == null;
|
||||
if (!updateTextComponent(true)) {
|
||||
if (!mySearchTextComponent.getText().equals(textToSet)) {
|
||||
mySearchTextComponent.setText(textToSet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mySearchTextComponent.getText().equals(textToSet)) {
|
||||
mySearchTextComponent.setText(textToSet);
|
||||
if (wasNull) {
|
||||
mySearchTextComponent.selectAll();
|
||||
}
|
||||
}
|
||||
mySearchTextComponent.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searchFieldDocumentChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
mySearchTextComponent.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
if (StringUtil.isEmpty(mySearchTextComponent.getText())) {
|
||||
close();
|
||||
}
|
||||
else {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myTargetComponent, true);
|
||||
addTextToRecent(mySearchTextComponent);
|
||||
}
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK),
|
||||
JComponent.WHEN_FOCUSED);
|
||||
if (!wasNull) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mySearchTextComponent.setCaretPosition(oldCaretPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
new VariantsCompletionAction(mySearchTextComponent); // It registers a shortcut set automatically on construction
|
||||
}
|
||||
|
||||
private void updateReplaceComponent(@NotNull String textToSet) {
|
||||
final int oldCaretPosition = myReplaceTextComponent != null ? myReplaceTextComponent.getCaretPosition() : 0;
|
||||
if (!updateTextComponent(false)) {
|
||||
return;
|
||||
}
|
||||
myReplaceTextComponent.setText(textToSet);
|
||||
|
||||
myReplaceTextComponent.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
replaceFieldDocumentChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!isMultiline()) {
|
||||
installReplaceOnEnterAction(myReplaceTextComponent);
|
||||
}
|
||||
|
||||
//myReplaceTextComponent.setText(myFindModel.getStringToReplace());
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myReplaceTextComponent.setCaretPosition(oldCaretPosition);
|
||||
}
|
||||
});
|
||||
|
||||
new VariantsCompletionAction(myReplaceTextComponent);
|
||||
myReplaceFieldWrapper.revalidate();
|
||||
myReplaceFieldWrapper.repaint();
|
||||
}
|
||||
|
||||
public void update(@NotNull String findText, @NotNull String replaceText, boolean replaceMode, boolean multiline) {
|
||||
setMultilineInternal(multiline);
|
||||
boolean needToResetSearchFocus = mySearchTextComponent != null && mySearchTextComponent.hasFocus();
|
||||
boolean needToResetReplaceFocus = myReplaceTextComponent != null && myReplaceTextComponent.hasFocus();
|
||||
updateSearchComponent(findText);
|
||||
updateReplaceComponent(replaceText);
|
||||
if (replaceMode) {
|
||||
if (myReplaceFieldWrapper.getParent() == null) {
|
||||
myLeftPanel.add(myReplaceFieldWrapper, BorderLayout.CENTER);
|
||||
}
|
||||
if (myReplaceToolbarWrapper.getParent() == null) {
|
||||
myRightPanel.add(myReplaceToolbarWrapper, BorderLayout.CENTER);
|
||||
}
|
||||
if (needToResetReplaceFocus) {
|
||||
myReplaceTextComponent.requestFocusInWindow();
|
||||
}
|
||||
} else {
|
||||
if (myReplaceFieldWrapper.getParent() != null) {
|
||||
myLeftPanel.remove(myReplaceFieldWrapper);
|
||||
}
|
||||
if (myReplaceToolbarWrapper.getParent() != null) {
|
||||
myRightPanel.remove(myReplaceToolbarWrapper);
|
||||
}
|
||||
}
|
||||
if (needToResetSearchFocus) mySearchTextComponent.requestFocusInWindow();
|
||||
updateBindings();
|
||||
updateActions();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void updateActions() {
|
||||
mySearchActionsToolbar1.updateActionsImmediately();
|
||||
mySearchActionsToolbar2.updateActionsImmediately();
|
||||
myReplaceActionsToolbar1.updateActionsImmediately();
|
||||
myReplaceActionsToolbar2.updateActionsImmediately();
|
||||
}
|
||||
|
||||
public void addTextToRecent(@NotNull JTextComponent textField) {
|
||||
final String text = textField.getText();
|
||||
if (text.length() > 0) {
|
||||
if (textField == mySearchTextComponent) {
|
||||
FindSettings.getInstance().addStringToFind(text);
|
||||
if (mySearchFieldWrapper.getTargetComponent() instanceof SearchTextField) {
|
||||
((SearchTextField)mySearchFieldWrapper.getTargetComponent()).addCurrentTextToHistory();
|
||||
}
|
||||
} else {
|
||||
FindSettings.getInstance().addStringToReplace(text);
|
||||
if (myReplaceFieldWrapper.getTargetComponent() instanceof SearchTextField) {
|
||||
((SearchTextField)myReplaceFieldWrapper.getTargetComponent()).addCurrentTextToHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateTextComponent(boolean search) {
|
||||
JTextComponent oldComponent = search ? mySearchTextComponent : myReplaceTextComponent;
|
||||
Color oldBackground = oldComponent != null ? oldComponent.getBackground() : null;
|
||||
final MyTextComponentWrapper wrapper = search ? mySearchFieldWrapper : myReplaceFieldWrapper;
|
||||
if (isMultiline() && oldComponent instanceof JTextArea) return false;
|
||||
if (!isMultiline() && oldComponent instanceof JTextField) return false;
|
||||
|
||||
final JTextComponent textComponent;
|
||||
if (isMultiline()) {
|
||||
SearchTextArea textArea = new SearchTextArea(search);
|
||||
textComponent = textArea.getTextArea();
|
||||
((JTextArea)textComponent).setColumns(25);
|
||||
((JTextArea)textComponent).setRows(2);
|
||||
wrapper.setContent(textArea);
|
||||
}
|
||||
else {
|
||||
SearchTextField searchTextField = new SearchTextField(true);
|
||||
searchTextField.setOpaque(false);
|
||||
textComponent = searchTextField.getTextEditor();
|
||||
searchTextField.getTextEditor().setColumns(25);
|
||||
if (UIUtil.isUnderGTKLookAndFeel()) {
|
||||
textComponent.setOpaque(false);
|
||||
}
|
||||
searchTextField.setHistorySize(20);
|
||||
searchTextField.setHistory(ContainerUtil.reverse(Arrays.asList(search ? FindSettings.getInstance().getRecentFindStrings()
|
||||
: FindSettings.getInstance().getRecentReplaceStrings())));
|
||||
textComponent.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final String text = textComponent.getText();
|
||||
setMultilineInternal(true);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ObjectUtils.assertNotNull(wrapper.getTextComponent()).setText(text + "\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_DOWN_MASK), JComponent.WHEN_FOCUSED);
|
||||
wrapper.setContent(searchTextField);
|
||||
}
|
||||
|
||||
UIUtil.addUndoRedoActions(textComponent);
|
||||
Utils.setSmallerFont(textComponent);
|
||||
|
||||
textComponent.putClientProperty("AuxEditorComponent", Boolean.TRUE);
|
||||
if (oldBackground != null) {
|
||||
textComponent.setBackground(oldBackground);
|
||||
}
|
||||
textComponent.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(final FocusEvent e) {
|
||||
textComponent.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(final FocusEvent e) {
|
||||
textComponent.repaint();
|
||||
}
|
||||
});
|
||||
installCloseOnEscapeAction(textComponent);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void searchFieldDocumentChanged() {
|
||||
if (mySearchTextComponent instanceof JTextArea) {
|
||||
adjustRows((JTextArea)mySearchTextComponent);
|
||||
}
|
||||
myEventDispatcher.getMulticaster().searchFieldDocumentChanged();
|
||||
}
|
||||
|
||||
private void replaceFieldDocumentChanged() {
|
||||
if (myReplaceTextComponent instanceof JTextArea) {
|
||||
adjustRows((JTextArea)myReplaceTextComponent);
|
||||
}
|
||||
myEventDispatcher.getMulticaster().replaceFieldDocumentChanged();
|
||||
}
|
||||
|
||||
private void multilineStateChanged() {
|
||||
myEventDispatcher.getMulticaster().multilineStateChanged();
|
||||
}
|
||||
|
||||
private static void adjustRows(@NotNull JTextArea area) {
|
||||
area.setRows(Math.max(2, Math.min(3, StringUtil.countChars(area.getText(),'\n')+1)));
|
||||
}
|
||||
|
||||
|
||||
private void installCloseOnEscapeAction(@NotNull JTextComponent c) {
|
||||
ActionListener action = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
close();
|
||||
}
|
||||
};
|
||||
c.registerKeyboardAction(action, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
|
||||
if (KeymapUtil.isEmacsKeymap()) {
|
||||
c.registerKeyboardAction(action, KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
|
||||
}
|
||||
}
|
||||
|
||||
private void installReplaceOnEnterAction(@NotNull JTextComponent c) {
|
||||
ActionListener action = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
replace();
|
||||
}
|
||||
};
|
||||
c.registerKeyboardAction(action, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED);
|
||||
}
|
||||
|
||||
private void updateBindings() {
|
||||
updateBindings(mySearchFieldActions, mySearchFieldWrapper);
|
||||
updateBindings(mySearchActionsToolbar1, mySearchFieldWrapper);
|
||||
updateBindings(mySearchActionsToolbar2, mySearchFieldWrapper);
|
||||
|
||||
updateBindings(myReplaceFieldActions, myReplaceFieldWrapper);
|
||||
updateBindings(myReplaceActionsToolbar1, myReplaceToolbarWrapper);
|
||||
updateBindings(myReplaceActionsToolbar2, myReplaceToolbarWrapper);
|
||||
}
|
||||
|
||||
private void updateBindings(@NotNull DefaultActionGroup group, @NotNull JComponent shortcutHolder) {
|
||||
updateBindings(ContainerUtil.immutableList(group.getChildActionsOrStubs()), shortcutHolder);
|
||||
}
|
||||
|
||||
private void updateBindings(@NotNull ActionToolbarImpl toolbar, @NotNull JComponent shortcutHolder) {
|
||||
updateBindings(toolbar.getActions(true), shortcutHolder);
|
||||
}
|
||||
|
||||
private void updateBindings(@NotNull List<? extends AnAction> actions, @NotNull JComponent shortcutHolder) {
|
||||
DataContext context = DataManager.getInstance().getDataContext(this);
|
||||
for (AnAction action : actions) {
|
||||
ShortcutSet shortcut = null;
|
||||
if (action instanceof ContextAwareShortcutProvider) {
|
||||
shortcut = ((ContextAwareShortcutProvider)action).getShortcut(context);
|
||||
}
|
||||
else if (action instanceof ShortcutProvider) {
|
||||
shortcut = ((ShortcutProvider)action).getShortcut();
|
||||
}
|
||||
if (shortcut != null) {
|
||||
action.registerCustomShortcutSet(shortcut, shortcutHolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl createSearchToolbar1(@NotNull DefaultActionGroup group) {
|
||||
ActionToolbarImpl toolbar = createToolbar(group);
|
||||
toolbar.setForceMinimumSize(true);
|
||||
toolbar.setReservePlaceAutoPopupIcon(false);
|
||||
toolbar.setSecondaryButtonPopupStateModifier(mySearchToolbar1PopupStateModifier);
|
||||
toolbar.setSecondaryActionsTooltip("More Options(" + ShowMoreOptions.SHORT_CUT + ")");
|
||||
new ShowMoreOptions(toolbar, mySearchFieldWrapper);
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl createSearchToolbar2(@NotNull DefaultActionGroup group) {
|
||||
return createToolbar(group);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl createReplaceToolbar1(@NotNull DefaultActionGroup group) {
|
||||
ActionToolbarImpl toolbar = createToolbar(group);
|
||||
toolbar.setForceMinimumSize(true);
|
||||
toolbar.setReservePlaceAutoPopupIcon(false);
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl createReplaceToolbar2(@NotNull DefaultActionGroup group) {
|
||||
return createToolbar(group);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl createToolbar(@NotNull ActionGroup group) {
|
||||
return tweakToolbar((ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, group, true));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbarImpl tweakToolbar(@NotNull ActionToolbarImpl toolbar) {
|
||||
toolbar.setTargetComponent(this);
|
||||
toolbar.setLayoutPolicy(ActionToolbar.AUTO_LAYOUT_POLICY);
|
||||
toolbar.setBorder(null);
|
||||
toolbar.setOpaque(false);
|
||||
Utils.setSmallerFontForChildren(toolbar);
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
|
||||
public interface Listener extends EventListener {
|
||||
void searchFieldDocumentChanged();
|
||||
|
||||
void replaceFieldDocumentChanged();
|
||||
|
||||
void multilineStateChanged();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Project myProject;
|
||||
private final JComponent myTargetComponent;
|
||||
|
||||
private DataProvider myDataProvider;
|
||||
|
||||
private Runnable myReplaceAction;
|
||||
private Runnable myCloseAction;
|
||||
|
||||
private DefaultActionGroup mySearchActions = new DefaultActionGroup("search bar 1", false);
|
||||
private DefaultActionGroup myExtraSearchActions = new DefaultActionGroup("search bar 2", false);
|
||||
private DefaultActionGroup mySearchFieldActions = new DefaultActionGroup("search field actions", false);
|
||||
private BooleanGetter mySearchToolbarModifiedFlagGetter = BooleanGetter.FALSE;
|
||||
|
||||
private DefaultActionGroup myReplaceActions = new DefaultActionGroup("replace bar 1", false);
|
||||
private DefaultActionGroup myExtraReplaceActions = new DefaultActionGroup("replace bar 1", false);
|
||||
private DefaultActionGroup myReplaceFieldActions = new DefaultActionGroup("replace field actions", false);
|
||||
|
||||
private Builder(@Nullable Project project, @NotNull JComponent component) {
|
||||
myProject = project;
|
||||
myTargetComponent = component;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder withDataProvider(@NotNull DataProvider provider) {
|
||||
myDataProvider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder withReplaceAction(@NotNull Runnable action) {
|
||||
myReplaceAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder withCloseAction(@NotNull Runnable action) {
|
||||
myCloseAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addSearchFieldActions(@NotNull AnAction... actions) {
|
||||
mySearchFieldActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addReplaceFieldActions(@NotNull AnAction... actions) {
|
||||
myReplaceFieldActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addPrimarySearchActions(@NotNull AnAction... actions) {
|
||||
mySearchActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addSecondarySearchActions(@NotNull AnAction... actions) {
|
||||
for (AnAction action : actions) {
|
||||
mySearchActions.addAction(action).setAsSecondary(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder withSecondarySearchActionsIsModifiedGetter(@NotNull BooleanGetter getter) {
|
||||
mySearchToolbarModifiedFlagGetter = getter;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addExtraSearchActions(@NotNull AnAction... actions) {
|
||||
myExtraSearchActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addPrimaryReplaceActions(@NotNull AnAction... actions) {
|
||||
myReplaceActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Builder addExtraReplaceAction(@NotNull AnAction... actions) {
|
||||
myExtraReplaceActions.addAll(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SearchReplaceComponent build() {
|
||||
return new SearchReplaceComponent(myProject,
|
||||
myTargetComponent,
|
||||
mySearchActions,
|
||||
mySearchToolbarModifiedFlagGetter,
|
||||
myExtraSearchActions,
|
||||
mySearchFieldActions,
|
||||
myReplaceActions,
|
||||
myExtraReplaceActions,
|
||||
myReplaceFieldActions,
|
||||
myReplaceAction,
|
||||
myCloseAction,
|
||||
myDataProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyTextComponentWrapper extends Wrapper {
|
||||
@Nullable
|
||||
public JTextComponent getTextComponent() {
|
||||
JComponent wrapped = getTargetComponent();
|
||||
return wrapped != null ? unwrapTextComponent(wrapped) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static JTextComponent unwrapTextComponent(@NotNull JComponent wrapped) {
|
||||
if (wrapped instanceof SearchTextField) {
|
||||
return ((SearchTextField)wrapped).getTextEditor();
|
||||
}
|
||||
if (wrapped instanceof SearchTextArea) {
|
||||
return ((SearchTextArea)wrapped).getTextArea();
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
-15
@@ -15,37 +15,48 @@
|
||||
*/
|
||||
package com.intellij.find;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.editorHeaderActions.Utils;
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.actionSystem.impl.InplaceActionButtonLook;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, FocusListener {
|
||||
private final JTextComponent myToWrap;
|
||||
class SearchTextArea extends NonOpaquePanel implements PropertyChangeListener, FocusListener {
|
||||
private final JTextArea myTextArea;
|
||||
|
||||
public SearchWrapper(JTextComponent toWrap, AnAction showHistoryAction) {
|
||||
myToWrap = toWrap;
|
||||
public SearchTextArea(boolean search) {
|
||||
myTextArea = new JTextArea();
|
||||
setBorder(JBUI.Borders.empty(6, 6, 6, 8));
|
||||
setLayout(new BorderLayout(JBUI.scale(4), 0));
|
||||
myToWrap.addPropertyChangeListener("background", this);
|
||||
myToWrap.addFocusListener(this);
|
||||
myToWrap.setBorder(null);
|
||||
myToWrap.setOpaque(false);
|
||||
JBScrollPane scrollPane = new JBScrollPane(myToWrap,
|
||||
myTextArea.addPropertyChangeListener("background", this);
|
||||
myTextArea.addFocusListener(this);
|
||||
myTextArea.setBorder(null);
|
||||
myTextArea.setOpaque(false);
|
||||
JBScrollPane scrollPane = new JBScrollPane(myTextArea,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
scrollPane.getVerticalScrollBar().setBackground(UIUtil.TRANSPARENT_COLOR);
|
||||
@@ -53,8 +64,9 @@ class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, Fo
|
||||
scrollPane.getViewport().setOpaque(false);
|
||||
scrollPane.setBorder(JBUI.Borders.emptyRight(2));
|
||||
scrollPane.setOpaque(false);
|
||||
ShowHistoryAction historyAction = new ShowHistoryAction(search);
|
||||
ActionButton button =
|
||||
new ActionButton(showHistoryAction, showHistoryAction.getTemplatePresentation(), ActionPlaces.UNKNOWN, new Dimension(JBUI.scale(16), JBUI.scale(16)));
|
||||
new ActionButton(historyAction, historyAction.getTemplatePresentation(), ActionPlaces.UNKNOWN, new Dimension(JBUI.scale(16), JBUI.scale(16)));
|
||||
button.setLook(new InplaceActionButtonLook());
|
||||
JPanel p = new NonOpaquePanel(new BorderLayout());
|
||||
p.add(button, BorderLayout.NORTH);
|
||||
@@ -62,6 +74,11 @@ class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, Fo
|
||||
add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JTextArea getTextArea() {
|
||||
return myTextArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return getPreferredSize();//myToWrap.getPreferredScrollableViewportSize();
|
||||
@@ -94,10 +111,10 @@ class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, Fo
|
||||
r.width -= JBUI.scale(9);
|
||||
r.height -= JBUI.scale(6);
|
||||
int arcSize = Math.min(25, r.height - 1) - 6;
|
||||
g.setColor(myToWrap.getBackground());
|
||||
boolean hasFocus = myToWrap.hasFocus();
|
||||
g.setColor(myTextArea.getBackground());
|
||||
boolean hasFocus = myTextArea.hasFocus();
|
||||
g.fillRoundRect(r.x, r.y + 1, r.width, r.height - 2, arcSize, arcSize);
|
||||
g.setColor(myToWrap.isEnabled() ? Gray._100 : Gray._83);
|
||||
g.setColor(myTextArea.isEnabled() ? Gray._100 : Gray._83);
|
||||
|
||||
if (hasFocus) {
|
||||
DarculaUIUtil.paintSearchFocusRing(g, r, arcSize + 6);
|
||||
@@ -111,4 +128,29 @@ class SearchWrapper extends NonOpaquePanel implements PropertyChangeListener, Fo
|
||||
}
|
||||
super.paint(graphics);
|
||||
}
|
||||
|
||||
private class ShowHistoryAction extends DumbAwareAction {
|
||||
private final boolean myShowSearchHistory;
|
||||
|
||||
public ShowHistoryAction(boolean search) {
|
||||
super((search ? "Search" : "Replace") + " History",
|
||||
(search ? "Search" : "Replace") + " history",
|
||||
IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/search.png", DarculaTextFieldUI.class, true));
|
||||
|
||||
myShowSearchHistory = search;
|
||||
|
||||
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_DOWN_MASK);
|
||||
registerCustomShortcutSet(new CustomShortcutSet(new KeyboardShortcut(stroke, null)), myTextArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("find.recent.search");
|
||||
String[] recent = myShowSearchHistory ? FindSettings.getInstance().getRecentFindStrings()
|
||||
: FindSettings.getInstance().getRecentReplaceStrings();
|
||||
String title = "Recent " + (myShowSearchHistory ? "Searches" : "Replaces");
|
||||
JBList historyList = new JBList((Object[])ArrayUtil.reverseArray(recent));
|
||||
Utils.showCompletionPopup(myTextArea, historyList, title, myTextArea, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-22
@@ -15,32 +15,18 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AddOccurrenceAction extends EditorHeaderAction implements DumbAware {
|
||||
public AddOccurrenceAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
|
||||
copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_SELECT_NEXT_OCCURENCE));
|
||||
getTemplatePresentation().setIcon(AllIcons.Actions.AddMulticaret);
|
||||
|
||||
registerShortcutsForComponent(Arrays.asList(getShortcutSet().getShortcuts()), editorSearchComponent.getSearchTextComponent());
|
||||
public class AddOccurrenceAction extends OccurrenceAction {
|
||||
public AddOccurrenceAction() {
|
||||
super(IdeActions.ACTION_SELECT_NEXT_OCCURENCE, AllIcons.Actions.AddMulticaret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myEditorSearchComponent.addNextOccurrence();
|
||||
e.getRequiredData(EditorSearchSession.SESSION_KEY).addNextOccurrence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
boolean isFind = !myEditorSearchComponent.getFindModel().isReplaceState();
|
||||
boolean hasMatches = myEditorSearchComponent.hasMatches();
|
||||
e.getPresentation().setVisible(isFind);
|
||||
e.getPresentation().setEnabled(isFind && hasMatches);
|
||||
}}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CloseOnESCAction extends EditorHeaderAction implements DumbAware {
|
||||
public CloseOnESCAction(EditorSearchComponent editorSearchComponent, JComponent textField) {
|
||||
super(editorSearchComponent);
|
||||
|
||||
ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
if (KeymapUtil.isEmacsKeymap()) {
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK), null));
|
||||
textField.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
CloseOnESCAction.this.actionPerformed(null);
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
|
||||
} else {
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), null));
|
||||
}
|
||||
|
||||
registerCustomShortcutSet(new CustomShortcutSet(shortcuts.toArray(new Shortcut[shortcuts.size()])), textField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myEditorSearchComponent.close();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.ShortcutSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ContextAwareShortcutProvider {
|
||||
@Nullable
|
||||
ShortcutSet getShortcut(@NotNull DataContext context);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class EditorHeaderAction extends AnAction {
|
||||
protected final EditorSearchComponent myEditorSearchComponent;
|
||||
|
||||
protected EditorHeaderAction(EditorSearchComponent editorSearchComponent) {
|
||||
myEditorSearchComponent = editorSearchComponent;
|
||||
}
|
||||
|
||||
protected void registerShortcutsForComponent(List<Shortcut> shortcuts, JComponent component) {
|
||||
registerCustomShortcutSet(
|
||||
new CustomShortcutSet(shortcuts.toArray(new Shortcut[shortcuts.size()])),
|
||||
component);
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction {
|
||||
private final FindModel.SearchContext myContext;
|
||||
|
||||
protected EditorHeaderSetSearchContextAction(@NotNull String text, @NotNull FindModel.SearchContext context) {
|
||||
super(text);
|
||||
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return session.getFindModel().getSearchContext() == myContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
session.getFindModel().setSearchContext(selected ? myContext : FindModel.SearchContext.ANY);
|
||||
}
|
||||
}
|
||||
+21
-6
@@ -1,20 +1,17 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public abstract class EditorHeaderToggleAction extends CheckboxAction implements DumbAware {
|
||||
|
||||
protected final EditorSearchComponent myEditorSearchComponent;
|
||||
|
||||
protected EditorHeaderToggleAction(EditorSearchComponent editorSearchComponent, String text) {
|
||||
protected EditorHeaderToggleAction(@NotNull String text) {
|
||||
super(text);
|
||||
myEditorSearchComponent = editorSearchComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,4 +31,22 @@ public abstract class EditorHeaderToggleAction extends CheckboxAction implements
|
||||
customComponent.setOpaque(false);
|
||||
return customComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
return search != null && isSelected(search);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean selected) {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
if (search != null) {
|
||||
setSelected(search, selected);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isSelected(@NotNull EditorSearchSession session);
|
||||
|
||||
protected abstract void setSelected(@NotNull EditorSearchSession session, boolean selected);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindUtil;
|
||||
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.ui.LayeredIcon;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -39,45 +40,58 @@ import javax.swing.*;
|
||||
* Time: 10:53
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class FindAllAction extends EditorHeaderAction implements DumbAware {
|
||||
public FindAllAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
Icon base = AllIcons.Actions.Find;
|
||||
Icon text = IconUtil.textToIcon("ALL", editorSearchComponent, JBUI.scale(6F));
|
||||
LayeredIcon icon = new LayeredIcon(2);
|
||||
icon.setIcon(base, 0);
|
||||
icon.setIcon(text, 1, 0, base.getIconHeight() - text.getIconHeight());
|
||||
getTemplatePresentation().setIcon(icon);
|
||||
public class FindAllAction extends AnAction implements ShortcutProvider, DumbAware {
|
||||
public FindAllAction() {
|
||||
getTemplatePresentation().setDescription("Export matches to Find tool window");
|
||||
getTemplatePresentation().setText("Find All");
|
||||
final AnAction findUsages = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES);
|
||||
if (findUsages != null) {
|
||||
registerCustomShortcutSet(findUsages.getShortcutSet(),
|
||||
editorSearchComponent.getSearchTextComponent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
Editor editor = e.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
Project project = e.getProject();
|
||||
if (project != null && !project.isDisposed()) {
|
||||
e.getPresentation().setEnabled(editor != null && myEditorSearchComponent.hasMatches() &&
|
||||
PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()) != null);
|
||||
}
|
||||
Editor editor = e.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
|
||||
updateTemplateIcon(search);
|
||||
e.getPresentation().setIcon(getTemplatePresentation().getIcon());
|
||||
e.getPresentation().setEnabled(editor != null && project != null && search != null &&
|
||||
!project.isDisposed() && search.hasMatches() &&
|
||||
PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
Editor editor = e.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
Project project = e.getProject();
|
||||
if (editor != null && project != null && !project.isDisposed()) {
|
||||
final FindModel model = FindManager.getInstance(project).getFindInFileModel();
|
||||
final FindModel realModel = (FindModel)model.clone();
|
||||
String text = myEditorSearchComponent.getTextInField();
|
||||
if (StringUtil.isEmpty(text)) return;
|
||||
realModel.setStringToFind(text);
|
||||
FindUtil.findAllAndShow(project, editor, realModel);
|
||||
}
|
||||
Editor editor = e.getRequiredData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
Project project = e.getRequiredData(CommonDataKeys.PROJECT);
|
||||
EditorSearchSession search = e.getRequiredData(EditorSearchSession.SESSION_KEY);
|
||||
|
||||
if (project.isDisposed()) return;
|
||||
|
||||
FindModel oldModel = FindManager.getInstance(project).getFindInFileModel();
|
||||
FindModel newModel = oldModel.clone();
|
||||
String text = search.getTextInField();
|
||||
if (StringUtil.isEmpty(text)) return;
|
||||
|
||||
newModel.setStringToFind(text);
|
||||
FindUtil.findAllAndShow(project, editor, newModel);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ShortcutSet getShortcut() {
|
||||
AnAction findUsages = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES);
|
||||
return findUsages != null ? findUsages.getShortcutSet() : null;
|
||||
}
|
||||
|
||||
private void updateTemplateIcon(@Nullable EditorSearchSession session) {
|
||||
if (session == null || getTemplatePresentation().getIcon() != null) return;
|
||||
|
||||
Icon base = AllIcons.Actions.Find;
|
||||
Icon text = IconUtil.textToIcon("ALL", session.getComponent(), JBUI.scale(6F));
|
||||
|
||||
LayeredIcon icon = new LayeredIcon(2);
|
||||
icon.setIcon(base, 0);
|
||||
icon.setIcon(text, 1, 0, base.getIconHeight() - text.getIconHeight());
|
||||
getTemplatePresentation().setIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,52 +15,28 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: zajac
|
||||
* Date: 05.03.11
|
||||
* Time: 10:40
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class NextOccurrenceAction extends EditorHeaderAction implements DumbAware {
|
||||
private final boolean mySearch;
|
||||
|
||||
public NextOccurrenceAction(EditorSearchComponent editorSearchComponent, JComponent shortcutHolder, boolean search) {
|
||||
super(editorSearchComponent);
|
||||
mySearch = search;
|
||||
copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_OCCURENCE));
|
||||
ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
ContainerUtil.addAll(shortcuts, ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT).getShortcutSet().getShortcuts());
|
||||
if (!editorSearchComponent.getFindModel().isMultiline()) {
|
||||
ContainerUtil
|
||||
.addAll(shortcuts, ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN).getShortcutSet().getShortcuts());
|
||||
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), null));
|
||||
}
|
||||
|
||||
registerShortcutsForComponent(shortcuts, shortcutHolder);
|
||||
public final class NextOccurrenceAction extends PrevNextOccurrenceAction {
|
||||
public NextOccurrenceAction(@NotNull Handler handler) {
|
||||
super(IdeActions.ACTION_NEXT_OCCURENCE, handler);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
myEditorSearchComponent.searchForward();
|
||||
protected List<Shortcut> getDefaultShortcuts() {
|
||||
return Utils.shortcutsOf(IdeActions.ACTION_FIND_NEXT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
String textToSearch = mySearch
|
||||
? myEditorSearchComponent.getSearchTextComponent().getText()
|
||||
: myEditorSearchComponent.getReplaceTextComponent().getText();
|
||||
e.getPresentation().setEnabled(myEditorSearchComponent.hasMatches() && !StringUtil.isEmpty(textToSearch));
|
||||
protected List<Shortcut> getSingleLineShortcuts() {
|
||||
return ContainerUtil.append(Utils.shortcutsOf(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN), CommonShortcuts.ENTER.getShortcuts());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.ShortcutProvider;
|
||||
import com.intellij.openapi.actionSystem.ShortcutSet;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public abstract class OccurrenceAction extends DumbAwareAction implements ShortcutProvider {
|
||||
protected OccurrenceAction(@NotNull String baseActionId, @NotNull Icon icon) {
|
||||
copyFrom(ActionManager.getInstance().getAction(baseActionId));
|
||||
getTemplatePresentation().setIcon(icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
if (search == null) {
|
||||
e.getPresentation().setEnabledAndVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFind = !search.getFindModel().isReplaceState();
|
||||
boolean hasMatches = search.hasMatches();
|
||||
e.getPresentation().setVisible(isFind);
|
||||
e.getPresentation().setEnabled(isFind && hasMatches);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ShortcutSet getShortcut() {
|
||||
return getShortcutSet();
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchReplaceComponent;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PrevNextOccurrenceAction extends DumbAwareAction implements ContextAwareShortcutProvider {
|
||||
private final Handler myHandler;
|
||||
|
||||
PrevNextOccurrenceAction(@NotNull String templateActionId, @NotNull Handler handler) {
|
||||
copyFrom(ActionManager.getInstance().getAction(templateActionId));
|
||||
myHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void update(AnActionEvent e) {
|
||||
myHandler.update(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void actionPerformed(AnActionEvent e) {
|
||||
myHandler.actionPerformed(e);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final ShortcutSet getShortcut(@NotNull DataContext context) {
|
||||
SearchReplaceComponent searchComponent = SearchReplaceComponent.COMPONENT_KEY.getData(context);
|
||||
boolean singleLine = searchComponent != null && !searchComponent.isMultiline();
|
||||
return Utils.shortcutSetOf(singleLine ? ContainerUtil.concat(getDefaultShortcuts(), getSingleLineShortcuts()) : getDefaultShortcuts());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract List<Shortcut> getDefaultShortcuts();
|
||||
|
||||
@NotNull
|
||||
protected abstract List<Shortcut> getSingleLineShortcuts();
|
||||
|
||||
|
||||
public interface Handler {
|
||||
void update(AnActionEvent e);
|
||||
|
||||
void actionPerformed(AnActionEvent e);
|
||||
}
|
||||
}
|
||||
+16
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,48 +15,32 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: zajac
|
||||
* Date: 05.03.11
|
||||
* Time: 10:40
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class PrevOccurrenceAction extends EditorHeaderAction implements DumbAware {
|
||||
|
||||
public PrevOccurrenceAction(EditorSearchComponent editorSearchComponent, JComponent shortcutHolder) {
|
||||
super(editorSearchComponent);
|
||||
|
||||
copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_OCCURENCE));
|
||||
|
||||
ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
ContainerUtil.addAll(shortcuts, ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_PREVIOUS).getShortcutSet().getShortcuts());
|
||||
if (!editorSearchComponent.getFindModel().isMultiline()) {
|
||||
ContainerUtil.addAll(shortcuts,
|
||||
ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP).getShortcutSet().getShortcuts());
|
||||
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK), null));
|
||||
}
|
||||
registerShortcutsForComponent(shortcuts, shortcutHolder);
|
||||
public final class PrevOccurrenceAction extends PrevNextOccurrenceAction {
|
||||
public PrevOccurrenceAction(@NotNull Handler handler) {
|
||||
super(IdeActions.ACTION_PREVIOUS_OCCURENCE, handler);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
myEditorSearchComponent.searchBackward();
|
||||
protected List<Shortcut> getDefaultShortcuts() {
|
||||
return Utils.shortcutsOf(IdeActions.ACTION_FIND_PREVIOUS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myEditorSearchComponent.hasMatches());
|
||||
protected List<Shortcut> getSingleLineShortcuts() {
|
||||
return ContainerUtil.append(Utils.shortcutsOf(IdeActions.ACTION_EDITOR_MOVE_CARET_UP),
|
||||
new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK), null));
|
||||
}
|
||||
}
|
||||
|
||||
+5
-22
@@ -15,35 +15,18 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class RemoveOccurrenceAction extends EditorHeaderAction implements DumbAware {
|
||||
public RemoveOccurrenceAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
|
||||
copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_UNSELECT_PREVIOUS_OCCURENCE));
|
||||
getTemplatePresentation().setIcon(AllIcons.Actions.RemoveMulticaret);
|
||||
|
||||
registerShortcutsForComponent(Arrays.asList(getShortcutSet().getShortcuts()), editorSearchComponent.getSearchTextComponent());
|
||||
public class RemoveOccurrenceAction extends OccurrenceAction {
|
||||
public RemoveOccurrenceAction() {
|
||||
super(IdeActions.ACTION_UNSELECT_PREVIOUS_OCCURENCE, AllIcons.Actions.RemoveMulticaret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myEditorSearchComponent.removeOccurrence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
boolean isFind = !myEditorSearchComponent.getFindModel().isReplaceState();
|
||||
boolean hasMatches = myEditorSearchComponent.hasMatches();
|
||||
e.getPresentation().setVisible(isFind);
|
||||
e.getPresentation().setEnabled(isFind && hasMatches);
|
||||
e.getRequiredData(EditorSearchSession.SESSION_KEY).removeOccurrence();
|
||||
}
|
||||
}
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ReplaceOnEnterAction extends EditorHeaderAction {
|
||||
public ReplaceOnEnterAction(EditorSearchComponent editorSearchComponent, JComponent shortcutHolder) {
|
||||
super(editorSearchComponent);
|
||||
ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), null));
|
||||
|
||||
registerCustomShortcutSet(new CustomShortcutSet(shortcuts.toArray(new Shortcut[shortcuts.size()])), shortcutHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myEditorSearchComponent.replaceCurrent();
|
||||
}
|
||||
}
|
||||
+17
-25
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -33,33 +33,25 @@ import java.util.Collections;
|
||||
* Time: 10:40
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class RestorePreviousSettingsAction extends EditorHeaderAction implements DumbAware {
|
||||
private final JComponent myShortcutHolder;
|
||||
private static final KeyboardShortcut SHORTCUT = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), null);
|
||||
|
||||
public RestorePreviousSettingsAction(EditorSearchComponent editorSearchComponent, JComponent shortcutHolder) {
|
||||
super(editorSearchComponent);
|
||||
myShortcutHolder = shortcutHolder;
|
||||
registerShortcutsForComponent(Collections.<Shortcut>singletonList(SHORTCUT), shortcutHolder);
|
||||
public class RestorePreviousSettingsAction extends AnAction implements ShortcutProvider, DumbAware {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
e.getPresentation().setEnabled(project != null && search != null && !project.isDisposed() &&
|
||||
search.getTextInField().isEmpty() &&
|
||||
FindManager.getInstance(project).getPreviousFindModel() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
final FindModel model = FindManager.getInstance(e.getProject()).getPreviousFindModel();
|
||||
if (model != null) {
|
||||
myEditorSearchComponent.getFindModel().copyFrom(model);
|
||||
}
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
FindModel findModel = e.getRequiredData(EditorSearchSession.SESSION_KEY).getFindModel();
|
||||
findModel.copyFrom(FindManager.getInstance(e.getProject()).getPreviousFindModel());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(
|
||||
e.getProject() != null
|
||||
&& myEditorSearchComponent.getSearchTextComponent().getText().isEmpty()
|
||||
&& FindManager.getInstance(e.getProject()).getPreviousFindModel() != null);
|
||||
}
|
||||
|
||||
public static String getAd() {
|
||||
return "Use " + KeymapUtil.getShortcutText(SHORTCUT) + " to restore previous find/replace settings";
|
||||
public ShortcutSet getShortcut() {
|
||||
return new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,39 +15,35 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SelectAllAction extends EditorHeaderAction implements DumbAware {
|
||||
public SelectAllAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
|
||||
copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_SELECT_ALL_OCCURRENCES));
|
||||
getTemplatePresentation().setIcon(AllIcons.Actions.CheckMulticaret);
|
||||
|
||||
List<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
ContainerUtil.addAll(shortcuts, getShortcutSet().getShortcuts());
|
||||
ContainerUtil.addAll(shortcuts, CommonShortcuts.ALT_ENTER.getShortcuts());
|
||||
registerShortcutsForComponent(shortcuts, editorSearchComponent.getSearchTextComponent());
|
||||
public class SelectAllAction extends OccurrenceAction {
|
||||
public SelectAllAction() {
|
||||
super(IdeActions.ACTION_SELECT_ALL_OCCURRENCES, AllIcons.Actions.CheckMulticaret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myEditorSearchComponent.selectAllOccurrences();
|
||||
myEditorSearchComponent.close();
|
||||
EditorSearchSession search = e.getRequiredData(EditorSearchSession.SESSION_KEY);
|
||||
search.selectAllOccurrences();
|
||||
search.close();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
boolean isFind = !myEditorSearchComponent.getFindModel().isReplaceState();
|
||||
boolean hasMatches = myEditorSearchComponent.hasMatches();
|
||||
e.getPresentation().setVisible(isFind);
|
||||
e.getPresentation().setEnabled(isFind && hasMatches);
|
||||
public ShortcutSet getShortcut() {
|
||||
List<Shortcut> shortcuts = ContainerUtil.newArrayList();
|
||||
AnAction selectAllOccurrences = ActionManager.getInstance().getAction(IdeActions.ACTION_SELECT_ALL_OCCURRENCES);
|
||||
if (selectAllOccurrences != null) {
|
||||
ContainerUtil.addAll(shortcuts, selectAllOccurrences.getShortcutSet().getShortcuts());
|
||||
}
|
||||
ContainerUtil.addAll(shortcuts, CommonShortcuts.ALT_ENTER.getShortcuts());
|
||||
return Utils.shortcutSetOf(shortcuts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* User: zajac
|
||||
*/
|
||||
public class ShowHistoryAction extends EditorHeaderAction implements DumbAware {
|
||||
private final JTextComponent myTextField;
|
||||
|
||||
public ShowHistoryAction(final JTextComponent textField, EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
myTextField = textField;
|
||||
getTemplatePresentation().setIcon(IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/search.png", DarculaTextFieldUI.class, true));
|
||||
final String s = myTextField == myEditorSearchComponent.getSearchTextComponent() ? "Search" : "Replace";
|
||||
getTemplatePresentation().setDescription(s + " history");
|
||||
getTemplatePresentation().setText(s + " History");
|
||||
|
||||
ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
|
||||
if (myTextField == myEditorSearchComponent.getSearchTextComponent()) {
|
||||
//ContainerUtil.addAll(shortcuts, ActionManager.getInstance().getAction(IdeActions.ACTION_FIND).getShortcutSet().getShortcuts());
|
||||
ContainerUtil.addAll(shortcuts, ActionManager.getInstance().getAction("IncrementalSearch").getShortcutSet().getShortcuts());
|
||||
}
|
||||
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_DOWN_MASK), null));
|
||||
|
||||
registerCustomShortcutSet(new CustomShortcutSet(shortcuts.toArray(new Shortcut[shortcuts.size()])), myTextField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setVisible(myEditorSearchComponent.getFindModel().isMultiline());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
myEditorSearchComponent.showHistory(false, myTextField);
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,10 @@ import java.awt.event.KeyEvent;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class ShowMoreOptions extends AnAction implements DumbAware {
|
||||
private final ActionToolbarImpl myToolbarComponent;
|
||||
public static final Shortcut SHORT_CUT = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK), null);
|
||||
|
||||
private final ActionToolbarImpl myToolbarComponent;
|
||||
|
||||
public ShowMoreOptions(ActionToolbarImpl toolbarComponent, JComponent shortcutHolder) {
|
||||
this.myToolbarComponent = toolbarComponent;
|
||||
registerCustomShortcutSet(new CustomShortcutSet(SHORT_CUT), shortcutHolder);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchReplaceComponent;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class StatusTextAction extends DumbAwareAction implements CustomComponentAction {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
String statusText = e.getData(SearchReplaceComponent.STATUS_TEXT_KEY);
|
||||
JLabel label = (JLabel)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY);
|
||||
if (label != null) {
|
||||
label.setText(StringUtil.notNullize(statusText));
|
||||
label.setVisible(StringUtil.isNotEmpty(statusText));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createCustomComponent(Presentation presentation) {
|
||||
JLabel label = new JLabel() {
|
||||
@Override
|
||||
public Font getFont() {
|
||||
Font font = super.getFont();
|
||||
return font != null ? font.deriveFont(Font.BOLD) : null;
|
||||
}
|
||||
};
|
||||
label.setBorder(JBUI.Borders.empty(2, 20, 0, 20));
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindUtil;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
@@ -9,6 +9,9 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -17,12 +20,24 @@ import com.intellij.openapi.project.DumbAware;
|
||||
* Time: 10:57
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class SwitchToFind extends EditorHeaderAction implements DumbAware {
|
||||
public SwitchToFind(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
public class SwitchToFind extends AnAction implements DumbAware {
|
||||
public SwitchToFind(@NotNull JComponent shortcutHolder) {
|
||||
AnAction findAction = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND);
|
||||
if (findAction != null) {
|
||||
registerCustomShortcutSet(findAction.getShortcutSet(), editorSearchComponent);
|
||||
registerCustomShortcutSet(findAction.getShortcutSet(), shortcutHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
if (KeymapUtil.isEmacsKeymap()) {
|
||||
// Emacs users are accustomed to the editor that executes 'find next' on subsequent pressing of shortcut that
|
||||
// activates 'incremental search'. Hence, we do the similar hack here for them.
|
||||
ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT).update(e);
|
||||
}
|
||||
else {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
e.getPresentation().setEnabledAndVisible(search != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +46,13 @@ public class SwitchToFind extends EditorHeaderAction implements DumbAware {
|
||||
if (KeymapUtil.isEmacsKeymap()) {
|
||||
// Emacs users are accustomed to the editor that executes 'find next' on subsequent pressing of shortcut that
|
||||
// activates 'incremental search'. Hence, we do the similar hack here for them.
|
||||
AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT);
|
||||
action.update(e);
|
||||
action.actionPerformed(e);
|
||||
ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_NEXT).actionPerformed(e);
|
||||
return;
|
||||
}
|
||||
|
||||
final FindModel findModel = myEditorSearchComponent.getFindModel();
|
||||
EditorSearchSession search = e.getRequiredData(EditorSearchSession.SESSION_KEY);
|
||||
final FindModel findModel = search.getFindModel();
|
||||
FindUtil.configureFindModel(false, null, findModel, false);
|
||||
myEditorSearchComponent.getSearchTextComponent().selectAll();
|
||||
search.getComponent().getSearchTextComponent().selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.execution.impl.ConsoleViewUtil;
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindUtil;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
@@ -9,6 +9,9 @@ import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -17,26 +20,26 @@ import com.intellij.openapi.editor.Editor;
|
||||
* Time: 10:57
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class SwitchToReplace extends EditorHeaderAction {
|
||||
|
||||
public SwitchToReplace(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent);
|
||||
public class SwitchToReplace extends AnAction {
|
||||
public SwitchToReplace(@NotNull JComponent shortcutHolder) {
|
||||
AnAction replaceAction = ActionManager.getInstance().getAction("Replace");
|
||||
if (replaceAction != null) {
|
||||
registerCustomShortcutSet(replaceAction.getShortcutSet(), editorSearchComponent);
|
||||
registerCustomShortcutSet(replaceAction.getShortcutSet(), shortcutHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final Editor editor = CommonDataKeys.EDITOR_EVEN_IF_INACTIVE.getData(e.getDataContext());
|
||||
e.getPresentation().setEnabled(editor != null && !ConsoleViewUtil.isConsoleViewEditor(editor));
|
||||
Editor editor = e.getData(CommonDataKeys.EDITOR_EVEN_IF_INACTIVE);
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
e.getPresentation().setEnabled(editor != null && search != null && !ConsoleViewUtil.isConsoleViewEditor(editor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final FindModel findModel = myEditorSearchComponent.getFindModel();
|
||||
EditorSearchSession search = e.getRequiredData(EditorSearchSession.SESSION_KEY);
|
||||
FindModel findModel = search.getFindModel();
|
||||
FindUtil.configureFindModel(true, null, findModel, false);
|
||||
myEditorSearchComponent.getSearchTextComponent().selectAll();
|
||||
search.getComponent().getSearchTextComponent().selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-17
@@ -15,24 +15,10 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
public class ToggleExceptCommentsAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "Except C&omments";
|
||||
|
||||
public ToggleExceptCommentsAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isExceptComments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_COMMENTS : FindModel.SearchContext.ANY);
|
||||
public class ToggleExceptCommentsAction extends EditorHeaderSetSearchContextAction {
|
||||
public ToggleExceptCommentsAction() {
|
||||
super("Except C&omments", FindModel.SearchContext.EXCEPT_COMMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-17
@@ -15,24 +15,10 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
public class ToggleExceptCommentsAndLiteralsAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "Except Comments and Li&terals";
|
||||
|
||||
public ToggleExceptCommentsAndLiteralsAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isExceptCommentsAndStringLiterals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS : FindModel.SearchContext.ANY);
|
||||
public class ToggleExceptCommentsAndLiteralsAction extends EditorHeaderSetSearchContextAction {
|
||||
public ToggleExceptCommentsAndLiteralsAction() {
|
||||
super("Except Comments and Li&terals", FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-17
@@ -15,24 +15,10 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
public class ToggleExceptLiteralsAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "Except L&iterals";
|
||||
|
||||
public ToggleExceptLiteralsAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isExceptStringLiterals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_STRING_LITERALS : FindModel.SearchContext.ANY);
|
||||
public class ToggleExceptLiteralsAction extends EditorHeaderSetSearchContextAction {
|
||||
public ToggleExceptLiteralsAction() {
|
||||
super("Except L&iterals", FindModel.SearchContext.EXCEPT_STRING_LITERALS);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-17
@@ -1,23 +1,9 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
public class ToggleInCommentsAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "In &Comments Only";
|
||||
|
||||
public ToggleInCommentsAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isInCommentsOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setSearchContext(state ? FindModel.SearchContext.IN_COMMENTS : FindModel.SearchContext.ANY);
|
||||
public class ToggleInCommentsAction extends EditorHeaderSetSearchContextAction {
|
||||
public ToggleInCommentsAction() {
|
||||
super("In &Comments Only", FindModel.SearchContext.IN_COMMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-17
@@ -1,23 +1,9 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
public class ToggleInLiteralsOnlyAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "In &Literals Only";
|
||||
|
||||
public ToggleInLiteralsOnlyAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isInStringLiteralsOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setSearchContext(state ? FindModel.SearchContext.IN_STRING_LITERALS : FindModel.SearchContext.ANY);
|
||||
public class ToggleInLiteralsOnlyAction extends EditorHeaderSetSearchContextAction {
|
||||
public ToggleInLiteralsOnlyAction() {
|
||||
super("In &Literals Only", FindModel.SearchContext.IN_STRING_LITERALS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,25 +15,23 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleMatchCase extends EditorHeaderToggleAction {
|
||||
private static final String CASE_SENSITIVE = "Match &Case";
|
||||
|
||||
public ToggleMatchCase(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, CASE_SENSITIVE);
|
||||
public ToggleMatchCase() {
|
||||
super("Match &Case");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isCaseSensitive();
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return session.getFindModel().isCaseSensitive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setCaseSensitive(state);
|
||||
FindSettings.getInstance().setLocalCaseSensitive(state);
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
session.getFindModel().setCaseSensitive(selected);
|
||||
FindSettings.getInstance().setLocalCaseSensitive(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
|
||||
|
||||
public class ToggleMultiline extends ToggleAction {
|
||||
private final EditorSearchComponent myEditorSearchComponent;
|
||||
|
||||
public ToggleMultiline(EditorSearchComponent editorSearchComponent) {
|
||||
super("Multiline", "Toggle Multiline Mode", AllIcons.Actions.ShowViewer);
|
||||
myEditorSearchComponent = editorSearchComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isMultiline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setMultiline(state);
|
||||
}
|
||||
}
|
||||
+15
-14
@@ -15,31 +15,32 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TogglePreserveCaseAction extends EditorHeaderToggleAction {
|
||||
private static final String TEXT = "Pr&eserve Case";
|
||||
|
||||
public TogglePreserveCaseAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isPreserveCase();
|
||||
public TogglePreserveCaseAction() {
|
||||
super("Pr&eserve Case");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
FindModel findModel = myEditorSearchComponent.getFindModel();
|
||||
e.getPresentation().setEnabled(!findModel.isRegularExpressions());
|
||||
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
FindModel findModel = search != null ? search.getFindModel() : null;
|
||||
e.getPresentation().setEnabled(findModel != null && !findModel.isRegularExpressions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setPreserveCase(state);
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return session.getFindModel().isPreserveCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
session.getFindModel().setPreserveCase(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,31 +15,28 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleRegex extends EditorHeaderToggleAction {
|
||||
|
||||
private static final String REGEX = "Re&gex";
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isRegularExpressions();
|
||||
public ToggleRegex() {
|
||||
super("Re&gex");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
final FindModel findModel = myEditorSearchComponent.getFindModel();
|
||||
findModel.setRegularExpressions(state);
|
||||
if (state) {
|
||||
findModel.setWholeWordsOnly(false);
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return session.getFindModel().isRegularExpressions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
FindModel findModel = session.getFindModel();
|
||||
findModel.setRegularExpressions(selected);
|
||||
if (selected) {
|
||||
findModel.setWholeWordsOnly(true);
|
||||
}
|
||||
FindSettings.getInstance().setLocalRegularExpressions(state);
|
||||
}
|
||||
|
||||
public ToggleRegex(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, REGEX);
|
||||
FindSettings.getInstance().setLocalRegularExpressions(selected);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-15
@@ -1,30 +1,29 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleSelectionOnlyAction extends EditorHeaderToggleAction {
|
||||
private static final String SELECTION_ONLY = "In &Selection";
|
||||
|
||||
public ToggleSelectionOnlyAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, SELECTION_ONLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return !myEditorSearchComponent.getFindModel().isGlobal();
|
||||
public ToggleSelectionOnlyAction() {
|
||||
super("In &Selection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
final boolean replaceState = myEditorSearchComponent.getFindModel().isReplaceState();
|
||||
e.getPresentation().setVisible(replaceState);
|
||||
e.getPresentation().setEnabled(replaceState);
|
||||
|
||||
EditorSearchSession session = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
e.getPresentation().setEnabledAndVisible(session != null && session.getFindModel().isReplaceState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myEditorSearchComponent.getFindModel().setGlobal(!state);
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return !session.getFindModel().isGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
session.getFindModel().setGlobal(!selected);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-15
@@ -1,31 +1,32 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleWholeWordsOnlyAction extends EditorHeaderToggleAction {
|
||||
private static final String WHOLE_WORDS_ONLY = "Wo&rds";
|
||||
|
||||
public ToggleWholeWordsOnlyAction(EditorSearchComponent editorSearchComponent) {
|
||||
super(editorSearchComponent, WHOLE_WORDS_ONLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myEditorSearchComponent.getFindModel().isWholeWordsOnly();
|
||||
public ToggleWholeWordsOnlyAction() {
|
||||
super("Wo&rds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
e.getPresentation().setEnabled(!myEditorSearchComponent.getFindModel().isRegularExpressions());
|
||||
e.getPresentation().setVisible(!myEditorSearchComponent.getFindModel().isMultiline());
|
||||
|
||||
EditorSearchSession session = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
e.getPresentation().setEnabled(session != null && !session.getFindModel().isRegularExpressions());
|
||||
e.getPresentation().setVisible(session != null && !session.getFindModel().isMultiline());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
FindSettings.getInstance().setLocalWholeWordsOnly(state);
|
||||
myEditorSearchComponent.getFindModel().setWholeWordsOnly(state);
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
return session.getFindModel().isWholeWordsOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
FindSettings.getInstance().setLocalWholeWordsOnly(selected);
|
||||
session.getFindModel().setWholeWordsOnly(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
public class Utils {
|
||||
private Utils() {
|
||||
@@ -62,4 +69,15 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CustomShortcutSet shortcutSetOf(@NotNull List<Shortcut> shortcuts) {
|
||||
return new CustomShortcutSet(shortcuts.toArray(new Shortcut[shortcuts.size()]));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Shortcut> shortcutsOf(@NotNull String actionId) {
|
||||
AnAction action = ActionManager.getInstance().getAction(actionId);
|
||||
return action == null ? ContainerUtil.<Shortcut>emptyList() : ContainerUtil.immutableList(action.getShortcutSet().getShortcuts());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,10 +240,9 @@ public class FindManagerImpl extends FindManager {
|
||||
public FindModel getFindNextModel(@NotNull final Editor editor) {
|
||||
if (myFindNextModel == null) return null;
|
||||
|
||||
final JComponent header = editor.getHeaderComponent();
|
||||
if (header instanceof EditorSearchComponent && !isSelectNextOccurrenceWasPerformed) {
|
||||
final EditorSearchComponent searchComponent = (EditorSearchComponent)header;
|
||||
final String textInField = searchComponent.getTextInField();
|
||||
EditorSearchSession search = EditorSearchSession.get(editor);
|
||||
if (search != null && !isSelectNextOccurrenceWasPerformed) {
|
||||
String textInField = search.getTextInField();
|
||||
if (!Comparing.equal(textInField, myFindInFileModel.getStringToFind()) && !textInField.isEmpty()) {
|
||||
FindModel patched = new FindModel();
|
||||
patched.copyFrom(myFindNextModel);
|
||||
@@ -930,16 +929,15 @@ public class FindManagerImpl extends FindManager {
|
||||
}
|
||||
|
||||
private static boolean tryToFindNextUsageViaEditorSearchComponent(Editor editor, SearchResults.Direction forwardOrBackward) {
|
||||
if (editor.getHeaderComponent() instanceof EditorSearchComponent) {
|
||||
EditorSearchComponent searchComponent = (EditorSearchComponent)editor.getHeaderComponent();
|
||||
if (searchComponent.hasMatches()) {
|
||||
if (forwardOrBackward == SearchResults.Direction.UP) {
|
||||
searchComponent.searchBackward();
|
||||
} else {
|
||||
searchComponent.searchForward();
|
||||
}
|
||||
return true;
|
||||
EditorSearchSession search = EditorSearchSession.get(editor);
|
||||
if (search != null && search.hasMatches()) {
|
||||
if (forwardOrBackward == SearchResults.Direction.UP) {
|
||||
search.searchBackward();
|
||||
}
|
||||
else {
|
||||
search.searchForward();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-3
@@ -42,7 +42,7 @@ public class LivePreviewController implements LivePreview.Delegate, FindUtil.Rep
|
||||
|
||||
public static final int USER_ACTIVITY_TRIGGERING_DELAY = 30;
|
||||
public static final int MATCHES_LIMIT = 10000;
|
||||
protected EditorSearchComponent myComponent;
|
||||
protected EditorSearchSession myComponent;
|
||||
|
||||
private int myUserActivityDelay = USER_ACTIVITY_TRIGGERING_DELAY;
|
||||
|
||||
@@ -111,7 +111,7 @@ public class LivePreviewController implements LivePreview.Delegate, FindUtil.Rep
|
||||
return myReplaceDenied;
|
||||
}
|
||||
|
||||
public LivePreviewController(SearchResults searchResults, @Nullable EditorSearchComponent component) {
|
||||
public LivePreviewController(SearchResults searchResults, @Nullable EditorSearchSession component) {
|
||||
mySearchResults = searchResults;
|
||||
myComponent = component;
|
||||
getEditor().getDocument().addDocumentListener(myDocumentListener);
|
||||
@@ -243,7 +243,7 @@ public class LivePreviewController implements LivePreview.Delegate, FindUtil.Rep
|
||||
mySuppressUpdate = false;
|
||||
}
|
||||
if (myComponent != null) {
|
||||
myComponent.addTextToRecent(myComponent.getReplaceTextComponent());
|
||||
myComponent.addTextToRecent(myComponent.getComponent().getReplaceTextComponent());
|
||||
myComponent.clearUndoInTextFields();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-12
@@ -17,20 +17,18 @@
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.execution.impl.ConsoleViewUtil;
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindUtil;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import javax.swing.*;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
|
||||
public class IncrementalFindAction extends EditorAction {
|
||||
public static class Handler extends EditorActionHandler {
|
||||
@@ -46,11 +44,10 @@ public class IncrementalFindAction extends EditorAction {
|
||||
public void execute(final Editor editor, DataContext dataContext) {
|
||||
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(editor.getComponent()));
|
||||
if (!editor.isOneLineMode()) {
|
||||
final JComponent headerComponent = editor.getHeaderComponent();
|
||||
if (headerComponent instanceof EditorSearchComponent) {
|
||||
EditorSearchComponent editorSearchComponent = (EditorSearchComponent)headerComponent;
|
||||
headerComponent.requestFocus();
|
||||
FindUtil.configureFindModel(myReplace, editor, editorSearchComponent.getFindModel(), false);
|
||||
EditorSearchSession search = EditorSearchSession.get(editor);
|
||||
if (search != null) {
|
||||
IdeFocusManager.getInstance(project).requestFocus(search.getComponent(), true);
|
||||
FindUtil.configureFindModel(myReplace, editor, search.getFindModel(), false);
|
||||
} else {
|
||||
FindManager findManager = FindManager.getInstance(project);
|
||||
FindModel model;
|
||||
@@ -61,9 +58,7 @@ public class IncrementalFindAction extends EditorAction {
|
||||
model.copyFrom(findManager.getFindInFileModel());
|
||||
}
|
||||
FindUtil.configureFindModel(myReplace, editor, model, true);
|
||||
final EditorSearchComponent header = new EditorSearchComponent(editor, project, model);
|
||||
editor.setHeaderComponent(header);
|
||||
header.requestFocus();
|
||||
EditorSearchSession.start(editor, model, project).getComponent().requestFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -16,8 +16,6 @@
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.find.*;
|
||||
import com.intellij.find.editorHeaderActions.EditorHeaderAction;
|
||||
import com.intellij.find.editorHeaderActions.SelectAllAction;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
|
||||
-2
@@ -16,8 +16,6 @@
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.find.*;
|
||||
import com.intellij.find.editorHeaderActions.AddOccurrenceAction;
|
||||
import com.intellij.find.editorHeaderActions.EditorHeaderAction;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
|
||||
-2
@@ -19,10 +19,8 @@ import com.intellij.codeInsight.editorActions.SelectWordUtil;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.find.EditorSearchComponent;
|
||||
import com.intellij.find.FindBundle;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.editorHeaderActions.EditorHeaderAction;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
|
||||
Reference in New Issue
Block a user