IDEA-65866, IDEA-65752: refactoring of interaction between header component and model.

This commit is contained in:
andrey zaytsev
2011-02-25 21:25:25 +03:00
parent 394743d7c7
commit 8dac8f0155
6 changed files with 351 additions and 121 deletions
@@ -31,6 +31,9 @@ import org.jetbrains.annotations.Nullable;
public abstract class FindManager {
public static final Topic<FindModelListener> FIND_MODEL_TOPIC = new Topic<FindModelListener>("FindManager's model changes",
FindModelListener.class);
public abstract FindModel createReplaceInFileModel();
/**
* Returns the find manager instance for the specified project.
*
@@ -17,11 +17,13 @@ package com.intellij.find;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -32,6 +34,26 @@ import java.util.regex.PatternSyntaxException;
public class FindModel extends UserDataHolderBase implements Cloneable {
private static final Logger LOG = Logger.getInstance("#com.intellij.find.FindModel");
public interface FindModelObserver {
void findModelChanged(FindModel findModel);
}
private CopyOnWriteArrayList<FindModelObserver> myObservers = new CopyOnWriteArrayList<FindModelObserver>();
public void addObserver(FindModelObserver observer) {
myObservers.add(observer);
}
public void removeObserver(FindModelObserver observer) {
myObservers.remove(observer);
}
private void notifyObservers() {
for (FindModelObserver observer : myObservers) {
observer.findModelChanged(this);
}
}
private String myStringToFind = "";
private String myStringToReplace = "";
private boolean isSearchHighlighters = false;
@@ -134,8 +156,12 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
*/
public void setStringToFind(@NotNull String s) {
LOG.assertTrue(s.length() > 0);
boolean changed = !StringUtil.equals(s, myStringToFind);
myStringToFind = s;
myPattern = NO_PATTERN;
if (changed) {
notifyObservers();
}
}
/**
@@ -154,7 +180,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param s the string to replace with.
*/
public void setStringToReplace(@NotNull String s) {
boolean changed = !StringUtil.equals(s, myStringToReplace);
myStringToReplace = s;
if (changed) {
notifyObservers();
}
}
/**
@@ -172,7 +202,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val true if the operation is a Replace, false if it is a Find.
*/
public void setReplaceState(boolean val) {
boolean changed = val != isReplaceState;
isReplaceState = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -190,7 +224,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val true if the origin is From Cursor, false if it is Entire Scope.
*/
public void setFromCursor(boolean val) {
boolean changed = val != isFromCursor;
isFromCursor = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -208,7 +246,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val true if the find is forward, false if it is backward.
*/
public void setForward(boolean val) {
boolean changed = val != isForward;
isForward = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -226,7 +268,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val the value of the Regular Expressions flag.
*/
public void setRegularExpressions(boolean val) {
boolean changed = val != isRegularExpressions;
isRegularExpressions = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -244,7 +290,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val the value of the Case Sensitive flag.
*/
public void setCaseSensitive(boolean val) {
boolean changed = val != isCaseSensitive;
isCaseSensitive = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -262,7 +312,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val true if the operation affects multiple files, false if it affects a single file.
*/
public void setMultipleFiles(boolean val) {
boolean changed = val != isMultipleFiles;
isMultipleFiles = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -280,7 +334,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param val the value of the Prompt on Replace flag.
*/
public void setPromptOnReplace(boolean val) {
boolean changed = val != isPromptOnReplace;
isPromptOnReplace = val;
if (changed) {
notifyObservers();
}
}
/**
@@ -298,7 +356,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param isWholeWordsOnly the value of the Whole Words Only flag.
*/
public void setWholeWordsOnly(boolean isWholeWordsOnly) {
boolean changed = isWholeWordsOnly != this.isWholeWordsOnly;
this.isWholeWordsOnly = isWholeWordsOnly;
if (changed) {
notifyObservers();
}
}
/**
@@ -316,7 +378,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param isGlobal true if the operation affects the entire file, false if it affects the selected text.
*/
public void setGlobal(boolean isGlobal) {
boolean changed = this.isGlobal != isGlobal;
this.isGlobal = isGlobal;
if (changed) {
notifyObservers();
}
}
/**
@@ -334,7 +400,9 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param replaceAll the value of the Replace All flag.
*/
public void setReplaceAll(boolean replaceAll) {
boolean changed = isReplaceAll != replaceAll;
isReplaceAll = replaceAll;
notifyObservers();
}
/**
@@ -352,7 +420,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param showInNewTab the value of the Open in New Tab flag.
*/
public void setOpenInNewTab(boolean showInNewTab) {
boolean changed = showInNewTab != isOpenNewTab;
isOpenNewTab = showInNewTab;
if (changed) {
notifyObservers();
}
}
/**
@@ -370,7 +442,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param showInNewTabEnabled true if Open in New Tab is enabled, false otherwise.
*/
public void setOpenInNewTabEnabled(boolean showInNewTabEnabled) {
boolean changed = isOpenInNewTabEnabled != showInNewTabEnabled;
isOpenInNewTabEnabled = showInNewTabEnabled;
if (changed) {
notifyObservers();
}
}
/**
@@ -388,7 +464,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param showInNewTabVisible true if Open in New Tab is visible, false otherwise.
*/
public void setOpenInNewTabVisible(boolean showInNewTabVisible) {
boolean changed = showInNewTabVisible != isOpenNewTabVisible;
isOpenNewTabVisible = showInNewTabVisible;
if (changed) {
notifyObservers();
}
}
/**
@@ -407,7 +487,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param directoryName the directory scope.
*/
public void setDirectoryName(String directoryName) {
boolean changed = !StringUtil.equals(directoryName, directoryName);
this.directoryName = directoryName;
if (changed) {
notifyObservers();
}
}
/**
@@ -425,7 +509,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param withSubdirectories true if directories are searched recursively, false otherwise.
*/
public void setWithSubdirectories(boolean withSubdirectories) {
boolean changed = withSubdirectories != isWithSubdirectories;
isWithSubdirectories = withSubdirectories;
if (changed) {
notifyObservers();
}
}
/**
@@ -445,7 +533,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param projectScope true if the whole project scope is selected, false otherwise.
*/
public void setProjectScope(boolean projectScope) {
boolean changed = projectScope != isProjectScope;
isProjectScope = projectScope;
if (changed) {
notifyObservers();
}
}
public Object clone() {
@@ -499,7 +591,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param search true if the operation moves between highlighted regions, false otherwise.
*/
public void setSearchHighlighters(boolean search) {
boolean changed = search != isSearchHighlighters;
isSearchHighlighters = search;
if (changed) {
notifyObservers();
}
}
/**
@@ -517,7 +613,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param fileFilter the file name filter text.
*/
public void setFileFilter(String fileFilter) {
boolean changed = !StringUtil.equals(fileFilter, this.fileFilter);
this.fileFilter = fileFilter;
if (changed) {
notifyObservers();
}
}
/**
@@ -538,7 +638,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @param moduleName the name of the module used as the scope.
*/
public void setModuleName(String moduleName) {
boolean changed = !StringUtil.equals(moduleName, this.moduleName);
this.moduleName = moduleName;
if (changed) {
notifyObservers();
}
}
/**
@@ -560,7 +664,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @since 5.1
*/
public void setFindAll(final boolean findAll) {
boolean changed = isFindAll != findAll;
isFindAll = findAll;
if (changed) {
notifyObservers();
}
}
/**
@@ -580,7 +688,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
* @since 5.1
*/
public void setFindAllEnabled(final boolean findAllEnabled) {
boolean changed = isFindAllEnabled != findAllEnabled;
isFindAllEnabled = findAllEnabled;
if (changed) {
notifyObservers();
}
}
public String getCustomScopeName() {
@@ -588,7 +700,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
public void setCustomScopeName(String customScopeName) {
boolean changed = !StringUtil.equals(customScopeName, this.customScopeName);
this.customScopeName = customScopeName;
if (changed) {
notifyObservers();
}
}
public SearchScope getCustomScope() {
@@ -596,7 +712,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
public void setCustomScope(final SearchScope customScope) {
boolean changed = this.customScope.equals(customScope);
this.customScope = customScope;
if (changed) {
notifyObservers();
}
}
public boolean isCustomScope() {
@@ -604,7 +724,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
public void setCustomScope(boolean customScope) {
boolean changed = isCustomScope != customScope;
isCustomScope = customScope;
if (changed) {
notifyObservers();
}
}
public boolean isInStringLiteralsOnly() {
@@ -612,7 +736,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
public void setInStringLiteralsOnly(boolean inStringLiteralsOnly) {
boolean changed = isInStringLiteralsOnly != inStringLiteralsOnly;
isInStringLiteralsOnly = inStringLiteralsOnly;
if (changed) {
notifyObservers();
}
}
public boolean isInCommentsOnly() {
@@ -620,7 +748,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
public void setInCommentsOnly(boolean inCommentsOnly) {
boolean changed = isInCommentsOnly != inCommentsOnly;
isInCommentsOnly = inCommentsOnly;
if (changed) {
notifyObservers();
}
}
private static final Pattern NO_PATTERN = Pattern.compile("");
@@ -19,6 +19,8 @@ package com.intellij.codeInsight.highlighting;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.find.EditorSearchComponent;
import com.intellij.find.FindManager;
import com.intellij.find.FindModel;
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.injection.InjectedLanguageManager;
@@ -29,6 +29,8 @@ import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.IncrementalFindAction;
import com.intellij.openapi.editor.actions.ReplaceAction;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.editor.event.SelectionEvent;
import com.intellij.openapi.editor.event.SelectionListener;
@@ -37,7 +39,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDocumentManager;
@@ -67,7 +68,8 @@ import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
public class EditorSearchComponent extends JPanel implements DataProvider, SelectionListener, SearchResults.SearchResultsListener {
public class EditorSearchComponent extends JPanel implements DataProvider, SelectionListener, SearchResults.SearchResultsListener,
FindModel.FindModelObserver {
private static final int MATCHES_LIMIT = 10000;
private final JLabel myMatchInfoLabel;
private final LinkLabel myClickToHighlightLabel;
@@ -104,11 +106,24 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
private final LivePreview myLivePreview;
private boolean myIsReplace;
private boolean myListeningSelection = false;
private SearchResults mySearchResults;
private Balloon myOptionsBalloon;
private final FindModel myFindModel;
private JCheckBox myCbMatchCase;
private JPanel myReplacementPane;
private static FindModel createDefaultFindModel(Project p) {
FindModel findModel = new FindModel();
findModel.copyFrom(FindManager.getInstance(p).getFindInFileModel());
return findModel;
}
public EditorSearchComponent(Editor editor, Project project) {
this(editor, project, createDefaultFindModel(project));
}
@Nullable
public Object getData(@NonNls final String dataId) {
if (PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.is(dataId)) {
@@ -117,10 +132,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
return null;
}
public EditorSearchComponent(final Editor e, Project p) {
this(e, p, false);
}
@Override
public void searchResultsUpdated(SearchResults sr) {
int count = sr.getActualFound();
@@ -163,11 +174,9 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
@Override
public void editorChanged(SearchResults sr, Editor oldEditor) { }
public EditorSearchComponent(final Editor editor, final Project project, boolean isReplace) {
public EditorSearchComponent(final Editor editor, final Project project, FindModel findModel) {
super(new BorderLayout(0, 0));
myIsReplace = isReplace;
myFindModel = findModel;
GRADIENT_C1 = getBackground();
GRADIENT_C2 = new Color(Math.max(0, GRADIENT_C1.getRed() - 0x18), Math.max(0, GRADIENT_C1.getGreen() - 0x18), Math.max(0, GRADIENT_C1.getBlue() - 0x18));
@@ -199,6 +208,8 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
group.add(new PrevOccurrenceAction());
group.add(new NextOccurrenceAction());
group.add(new FindAllAction());
group.add(new IncrementalFindAction());
group.add(new ReplaceAction());
final ActionToolbar tb = ActionManager.getInstance().createActionToolbar("SearchBar", group, true);
tb.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
@@ -207,7 +218,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
myToolbarComponent.setOpaque(false);
leadPanel.add(myToolbarComponent);
final JCheckBox cbMatchCase = new NonFocusableCheckBox("Case sensitive");
myCbMatchCase = new NonFocusableCheckBox("Case sensitive");
myCbWholeWords = new NonFocusableCheckBox("Match whole words only");
myCbRegexp = new NonFocusableCheckBox("Regex");
myCbInComments = new NonFocusableCheckBox("Search in comments only");
@@ -216,7 +227,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
myOptionsPane = new JPanel();
myOptionsPane.setLayout(new BoxLayout(myOptionsPane, BoxLayout.Y_AXIS));
leadPanel.add(cbMatchCase);
leadPanel.add(myCbMatchCase);
myOptionsPane.add(myCbWholeWords);
leadPanel.add(myCbRegexp);
if (FindManagerImpl.ourHasSearchInCommentsAndLiterals) {
@@ -238,38 +249,40 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}
});
leadPanel.add(myMoreOptionsButton);
cbMatchCase.setSelected(isCaseSensitive());
myCbWholeWords.setSelected(isWholeWords());
myCbRegexp.setSelected(isRegexp());
myCbInComments.setSelected(isInComments());
myCbInLiterals.setSelected(isInLiterals());
myFindModel.addObserver(new FindModel.FindModelObserver() {
@Override
public void findModelChanged(FindModel findModel) {
syncFindModels(FindManager.getInstance(myProject).getFindInFileModel(), myFindModel);
updateUIWithFindModel();
updateResults(true);
}
});
cbMatchCase.setMnemonic('C');
FindManager.getInstance(myProject).getFindInFileModel().addObserver(this);
updateUIWithFindModel();
myCbMatchCase.setMnemonic('C');
myCbWholeWords.setMnemonic('M');
myCbRegexp.setMnemonic('x');
myCbInComments.setMnemonic('o');
myCbInLiterals.setMnemonic('l');
setSmallerFontAndOpaque(myCbWholeWords);
setSmallerFontAndOpaque(cbMatchCase);
setSmallerFontAndOpaque(myCbMatchCase);
setSmallerFontAndOpaque(myCbRegexp);
setSmallerFontAndOpaque(myCbInComments);
setSmallerFontAndOpaque(myCbInLiterals);
if (myIsReplace) {
configureReplacementPane();
myReplaceField.putClientProperty("AuxEditorComponent", Boolean.TRUE);
}
cbMatchCase.addActionListener(new ActionListener() {
myCbMatchCase.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final boolean b = cbMatchCase.isSelected();
final boolean b = myCbMatchCase.isSelected();
FindManager.getInstance(myProject).getFindInFileModel().setCaseSensitive(b);
FindSettings.getInstance().setLocalCaseSensitive(b);
updateResults(true);
}
});
@@ -278,7 +291,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
final boolean b = myCbWholeWords.isSelected();
FindManager.getInstance(myProject).getFindInFileModel().setWholeWordsOnly(b);
FindSettings.getInstance().setLocalWholeWordsOnly(b);
updateResults(true);
}
});
@@ -286,11 +298,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
public void actionPerformed(final ActionEvent e) {
final boolean b = myCbRegexp.isSelected();
FindManager.getInstance(myProject).getFindInFileModel().setRegularExpressions(b);
myCbWholeWords.setEnabled(!b);
if (myPreserveCase != null) {
myPreserveCase.setEnabled(!b);
}
updateResults(true);
}
});
@@ -298,7 +305,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
public void actionPerformed(final ActionEvent e) {
final boolean b = myCbInComments.isSelected();
FindManager.getInstance(myProject).getFindInFileModel().setInCommentsOnly(b);
updateResults(true);
}
});
@@ -306,7 +312,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
public void actionPerformed(final ActionEvent e) {
final boolean b = myCbInLiterals.isSelected();
FindManager.getInstance(myProject).getFindInFileModel().setInStringLiteralsOnly(b);
updateResults(true);
}
});
@@ -345,6 +350,17 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
tailPanel.add(closeLabel, BorderLayout.EAST);
configureTextField(mySearchField);
mySearchField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
setMatchesLimit(MATCHES_LIMIT);
String text = mySearchField.getText();
if (!StringUtil.isEmpty(text)) {
myFindModel.setStringToFind(text);
updateResults(true);
}
}
});
setSmallerFont(mySearchField);
mySearchField.registerKeyboardAction(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
@@ -359,7 +375,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK),
JComponent.WHEN_FOCUSED);
final String initialText = myEditor.getSelectionModel().getSelectedText();
final String initialText = myFindModel.getStringToFind();
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
@@ -368,8 +384,87 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
});
new VariantsCompletionAction(); // It registers a shortcut set automatically on construction
}
@Override
public void findModelChanged(FindModel findModel) {
syncFindModels(myFindModel, findModel);
}
public boolean isRegexp() {
return myFindModel.isRegularExpressions();
}
public void setRegexp(boolean val) {
myFindModel.setRegularExpressions(val);
}
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.setInCommentsOnly(from.isInCommentsOnly());
to.setInStringLiteralsOnly(from.isInStringLiteralsOnly());
}
private void updateFindModelWithUI() {
myFindModel.setCaseSensitive(myCbMatchCase.isSelected());
myFindModel.setWholeWordsOnly(myCbWholeWords.isSelected());
myFindModel.setRegularExpressions(myCbRegexp.isSelected());
myFindModel.setInCommentsOnly(myCbInComments.isSelected());
myFindModel.setInStringLiteralsOnly(myCbInLiterals.isSelected());
myFindModel.setFromCursor(false);
myFindModel.setSearchHighlighters(true);
}
private void updateUIWithFindModel() {
myCbMatchCase.setSelected(myFindModel.isCaseSensitive());
myCbWholeWords.setSelected(myFindModel.isWholeWordsOnly());
myCbWholeWords.setEnabled(!myFindModel.isRegularExpressions());
myCbRegexp.setSelected(myFindModel.isRegularExpressions());
myCbInComments.setSelected(myFindModel.isInCommentsOnly());
myCbInLiterals.setSelected(myFindModel.isInStringLiteralsOnly());
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
String stringToFind = myFindModel.getStringToFind();
boolean changed = StringUtil.equals(stringToFind, mySearchField.getText());
mySearchField.setText(stringToFind);
if (changed) {
updateResults(true);
}
}
});
setTrackingSelection(!myFindModel.isGlobal());
if (myFindModel.isReplaceState() && myReplacementPane == null) {
configureReplacementPane();
} else if (!myFindModel.isReplaceState() && myReplacementPane != null) {
remove(myReplacementPane);
myReplacementPane = null;
}
if (myFindModel.isReplaceState()) {
mySelectionOnly.setSelected(!myFindModel.isGlobal());
myPreserveCase.setSelected(myFindModel.isPreserveCase());
myPreserveCase.setEnabled(!myFindModel.isRegularExpressions());
myPreserveCase.setEnabled(!myFindModel.isWholeWordsOnly());
updateExcludeStatus();
}
}
private static FindModel createFindModel(FindModel findInFileModel, boolean isReplace) {
FindModel result = new FindModel();
result.copyFrom(findInFileModel);
if (isReplace) {
result.setReplaceState(isReplace);
}
return result;
}
private void setMatchesLimit(int value) {
@@ -377,43 +472,44 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}
private void configureReplacementPane() {
JPanel replacement = createLeadPane();
myReplacementPane = createLeadPane();
myReplaceField = createTextField();
configureTextField(myReplaceField);
myReplaceField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
setMatchesLimit(MATCHES_LIMIT);
myFindModel.setStringToReplace(myReplaceField.getText());
}
});
myReplaceField.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
myLivePreviewController.performReplace();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED);
replacement.add(myReplaceField);
add(replacement, BorderLayout.SOUTH);
myReplaceField.setText(myFindModel.getStringToReplace());
myReplacementPane.add(myReplaceField);
add(myReplacementPane, BorderLayout.SOUTH);
myPreserveCase = new JCheckBox("Preserve case");
mySelectionOnly = new JCheckBox("Selection only");
final FindModel findInFileModel = FindManager.getInstance(myProject).getFindInFileModel();
myPreserveCase.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
final boolean b = myPreserveCase.isSelected();
findInFileModel.setPreserveCase(b);
updateResults(true);
myFindModel.setPreserveCase(b);
}
});
myPreserveCase.setMnemonic('P');
mySelectionOnly.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
updateModelWithSelectionMode(findInFileModel);
updateResults(true);
final boolean b = mySelectionOnly.isSelected();
myFindModel.setGlobal(!b);
}
});
mySelectionOnly.setMnemonic('S');
updateModelWithSelectionMode(findInFileModel);
mySelectionOnly.setSelected(!findInFileModel.isGlobal());
myPreserveCase.setSelected(findInFileModel.isPreserveCase());
myPreserveCase.setEnabled(!findInFileModel.isRegularExpressions());
myReplaceButton = new JButton("Replace");
myReplaceButton.addActionListener(new ActionListener() {
@@ -434,7 +530,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
myReplaceAllButton.setMnemonic('a');
myExcludeButton = new JButton("");
updateExcludeStatus();
myExcludeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
@@ -443,9 +539,9 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
});
myExcludeButton.setMnemonic('l');
replacement.add(myReplaceButton);
replacement.add(myReplaceAllButton);
replacement.add(myExcludeButton);
myReplacementPane.add(myReplaceButton);
myReplacementPane.add(myReplaceAllButton);
myReplacementPane.add(myExcludeButton);
myOptionsPane.add(mySelectionOnly);
myOptionsPane.add(myPreserveCase);
@@ -457,6 +553,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
setSmallerFontAndOpaque(mySelectionOnly);
setSmallerFontAndOpaque(myPreserveCase);
setSmallerFont(myReplaceField);
myReplaceField.putClientProperty("AuxEditorComponent", Boolean.TRUE);
}
private void updateExcludeStatus() {
@@ -474,11 +571,16 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}
}
private void updateModelWithSelectionMode(FindModel findInFileModel) {
private void updateModelWithSelectionMode() {
final boolean b = mySelectionOnly.isSelected();
findInFileModel.setGlobal(!b);
myFindModel.setGlobal(!b);
}
private void setTrackingSelection(boolean b) {
if (b) {
myEditor.getSelectionModel().addSelectionListener(this);
if (!myListeningSelection) {
myEditor.getSelectionModel().addSelectionListener(this);
}
} else {
if (myListeningSelection) {
myEditor.getSelectionModel().removeSelectionListener(this);
@@ -518,12 +620,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}
});
searchField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
setMatchesLimit(MATCHES_LIMIT);
updateResults(true);
}
});
searchField.registerKeyboardAction(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
@@ -544,7 +641,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
public void setInitialText(final String initialText) {
final String text = initialText != null ? initialText : "";
if (text.contains("\n")) {
setRegexp(true);
myFindModel.setRegularExpressions(true);
setTextInField(StringUtil.escapeToRegexp(text));
}
else {
@@ -613,6 +710,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
myEditor.getSelectionModel().removeSelection();
}
IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), false);
FindManager.getInstance(myProject).getFindInFileModel().removeObserver(this);
mySearchResults.dispose();
myLivePreview.cleanUp();
myEditor.setHeaderComponent(null);
@@ -656,14 +754,9 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
nothingToSearchFor();
}
else {
final FindModel model = new FindModel();
model.setCaseSensitive(isCaseSensitive());
model.setInCommentsOnly(isInComments());
model.setInStringLiteralsOnly(isInLiterals());
setRegularBackground();
if (isRegexp()) {
model.setWholeWordsOnly(false);
model.setRegularExpressions(true);
if (myFindModel.isRegularExpressions()) {
try {
Pattern.compile(text);
}
@@ -675,31 +768,18 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
return;
}
}
else {
model.setWholeWordsOnly(isWholeWords());
model.setRegularExpressions(false);
}
model.setFromCursor(false);
model.setStringToFind(text);
model.setSearchHighlighters(true);
final FindManager findManager = FindManager.getInstance(myProject);
if (allowedToChangedEditorSelection) {
findManager.setFindWasPerformed();
FindModel copy = new FindModel();
copy.copyFrom(model);
copy.copyFrom(myFindModel);
copy.setReplaceState(false);
findManager.setFindNextModel(copy);
}
if (myIsReplace) {
model.setReplaceState(true);
model.setStringToReplace(myReplaceField.getText());
model.setPromptOnReplace(false);
model.setGlobal(!mySelectionOnly.isSelected());
model.setPreserveCase(myPreserveCase.isEnabled() && myPreserveCase.isSelected());
}
myLivePreviewController.updateInBackground(model, allowedToChangedEditorSelection);
myLivePreviewController.updateInBackground(myFindModel, allowedToChangedEditorSelection);
}
}
@@ -728,35 +808,11 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
return mySearchField.getText();
}
private boolean isWholeWords() {
return FindManager.getInstance(myProject).getFindInFileModel().isWholeWordsOnly();
}
private boolean isInComments() {
return FindManager.getInstance(myProject).getFindInFileModel().isInCommentsOnly();
}
private boolean isInLiterals() {
return FindManager.getInstance(myProject).getFindInFileModel().isInStringLiteralsOnly();
}
private boolean isCaseSensitive() {
return FindManager.getInstance(myProject).getFindInFileModel().isCaseSensitive();
}
public boolean isRegexp() {
return myCbRegexp.isSelected() || FindManager.getInstance(myProject).getFindInFileModel().isRegularExpressions();
}
public void setRegexp(boolean r) {
myCbRegexp.setSelected(r);
myCbWholeWords.setEnabled(!r);
updateResults(false);
}
public void setTextInField(final String text) {
mySearchField.setText(text);
updateResults(true);
if (!StringUtil.isEmpty(text)) {
myFindModel.setStringToFind(text);
}
}
private class PrevOccurrenceAction extends AnAction implements DumbAware {
@@ -770,7 +826,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK), null));
registerShortcutsForComponent(shortcuts, mySearchField, this);
if (myIsReplace) {
if (myFindModel.isReplaceState()) {
registerShortcutsForComponent(shortcuts, myReplaceField, this);
}
}
@@ -804,7 +860,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
shortcuts.add(new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), null));
registerShortcutsForComponent(shortcuts, mySearchField, this);
if (myIsReplace) {
if (myFindModel.isReplaceState()) {
registerShortcutsForComponent(shortcuts, myReplaceField, this);
}
}
@@ -114,6 +114,15 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
myFindInProjectModel.setMultipleFiles(true);
}
@Override
public FindModel createReplaceInFileModel() {
FindModel model = new FindModel();
model.copyFrom(getFindInFileModel());
model.setReplaceState(true);
model.setPromptOnReplace(false);
return model;
}
public Element getState() {
Element element = new Element("FindManager");
final Element findUsages = new Element(FIND_USAGES_MANAGER_ELEMENT);
@@ -17,6 +17,8 @@
package com.intellij.openapi.editor.actions;
import com.intellij.find.EditorSearchComponent;
import com.intellij.find.FindManager;
import com.intellij.find.FindModel;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
@@ -24,6 +26,7 @@ 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 com.intellij.openapi.util.text.StringUtil;
import javax.swing.*;
@@ -41,18 +44,43 @@ public class IncrementalFindAction extends EditorAction {
final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(editor.getComponent()));
if (!editor.isOneLineMode()) {
final JComponent headerComponent = editor.getHeaderComponent();
String selectedText = editor.getSelectionModel().getSelectedText();
if (headerComponent instanceof EditorSearchComponent) {
if (myReplace) {
((EditorSearchComponent)headerComponent).replaceCurrent();
} else {
((EditorSearchComponent) headerComponent).setInitialText(editor.getSelectionModel().getSelectedText());
EditorSearchComponent editorSearchComponent = (EditorSearchComponent)headerComponent;
if (!myReplace) {
editorSearchComponent.setInitialText(selectedText);
headerComponent.requestFocus();
}
if (myReplace != editorSearchComponent.getFindModel().isReplaceState()){
editorSearchComponent.getFindModel().setReplaceState(myReplace);
}
}
else {
final EditorSearchComponent header = new EditorSearchComponent(editor, project, myReplace);
FindManager findManager = FindManager.getInstance(project);
FindModel model = null;
if (myReplace) {
model = findManager.createReplaceInFileModel();
if (!StringUtil.isEmpty(selectedText)) {
if (selectedText.indexOf('\n') >= 0) {
model.setGlobal(false);
}
else {
model.setStringToFind(selectedText);
model.setGlobal(true);
}
}
else {
model.setGlobal(true);
}
} else {
model = new FindModel();
model.copyFrom(findManager.getFindInFileModel());
}
if (selectedText != null && model.isGlobal()) {
model.setStringToFind(selectedText);
}
final EditorSearchComponent header = new EditorSearchComponent(editor, project, model);
editor.setHeaderComponent(header);
header.requestFocus();
}
}