Extract search and replace component

This commit is contained in:
Sergey Savenko
2015-09-28 21:07:49 +03:00
parent cfdbb5a534
commit 4fe0b96f70
46 changed files with 1992 additions and 1529 deletions
@@ -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) {
@@ -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();
}
}
}
@@ -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);
}
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -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));
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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,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);
}
}
@@ -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);
}
}
@@ -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;
}
@@ -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();
}
}
@@ -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();
}
}
}
@@ -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;
@@ -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;
@@ -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;