This commit is contained in:
Gregory.Shrago
2014-08-15 22:21:07 +04:00
parent 58af58ba53
commit bf7502ae09
4 changed files with 61 additions and 81 deletions
@@ -16,26 +16,21 @@
package org.intellij.lang.regexp.intention;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.BalloonImpl;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
@@ -44,6 +39,7 @@ import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.regexp.RegExpLanguage;
import org.intellij.lang.regexp.RegExpModifierProvider;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
@@ -57,54 +53,40 @@ import java.util.regex.Pattern;
*/
public class CheckRegExpForm {
private static final String LAST_EDITED_REGEXP = "last.edited.regexp";
private Pair<PsiFile, Ref<Balloon>> myParams;
private final PsiFile myRegexpFile;
private EditorTextField mySampleText; //TODO[kb]: make it multiline
private EditorTextField myRegExp;
private JPanel myRootPanel;
private JBLabel myMessage;
private Ref<Balloon> myRef;
private Project myProject;
public CheckRegExpForm(Pair<PsiFile, Ref<Balloon>> params) {
myParams = params;
public CheckRegExpForm(@NotNull PsiFile regexpFile) {
myRegexpFile = regexpFile;
}
private void createUIComponents() {
PsiFile file = myParams.first;
myProject = file.getProject();
myRef = myParams.second;
Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
myProject = myRegexpFile.getProject();
Document document = PsiDocumentManager.getInstance(myProject).getDocument(myRegexpFile);
myRegExp = new EditorTextField(document, myProject, RegExpLanguage.INSTANCE.getAssociatedFileType());
myRegExp.setPreferredWidth(Math.max(300, myRegExp.getPreferredSize().width));
final String sampleText = PropertiesComponent.getInstance(myProject).getValue(LAST_EDITED_REGEXP, "Sample Text");
mySampleText = new EditorTextField(sampleText, myProject, PlainTextFileType.INSTANCE);
mySampleText.setBorder(
new CompoundBorder(new EmptyBorder(2, 2, 2, 4), new LineBorder(UIUtil.isUnderDarcula() ? Gray._100 : UIUtil.getBorderColor())));
new CompoundBorder(new EmptyBorder(2, 2, 2, 4), new LineBorder(UIUtil.isUnderDarcula() ? Gray._100 : JBColor.border())));
mySampleText.setOneLineMode(false);
mySampleText.addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myRootPanel.revalidate();
final Balloon balloon = myRef.get();
if (balloon != null) {
balloon.revalidate();
}
}
});
}
});
myRootPanel = new JPanel(new BorderLayout()) {
Disposable disposable;
@Override
public void addNotify() {
super.addNotify();
disposable = Disposer.newDisposable();
IdeFocusManager.getGlobalInstance().requestFocus(mySampleText, true);
new AnAction(){
@@ -112,26 +94,10 @@ public class CheckRegExpForm {
public void actionPerformed(AnActionEvent e) {
IdeFocusManager.findInstance().requestFocus(myRegExp.getFocusTarget(), true);
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("shift TAB"), mySampleText, myRef.get());
final AnAction escaper = new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
myRef.get().hide();
}
};
escaper.registerCustomShortcutSet(CommonShortcuts.ESCAPE, myRegExp.getFocusTarget(), myRef.get());
escaper.registerCustomShortcutSet(CommonShortcuts.ESCAPE, mySampleText.getFocusTarget(), myRef.get());
}.registerCustomShortcutSet(CustomShortcutSet.fromString("shift TAB"), mySampleText);
myRef.get().addListener(new JBPopupAdapter() {
@Override
public void onClosed(LightweightWindowEvent event) {
PropertiesComponent.getInstance(myProject).setValue(LAST_EDITED_REGEXP, mySampleText.getText());
}
});
final Alarm updater = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myRef.get());
final DocumentAdapter documentListener = new DocumentAdapter() {
final Alarm updater = new Alarm(Alarm.ThreadToUse.SWING_THREAD, disposable);
DocumentAdapter documentListener = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
updater.cancelAllRequests();
@@ -151,22 +117,33 @@ public class CheckRegExpForm {
updateBalloon();
mySampleText.selectAll();
}
@Override
public void removeNotify() {
super.removeNotify();
Disposer.dispose(disposable);
PropertiesComponent.getInstance(myProject).setValue(LAST_EDITED_REGEXP, mySampleText.getText());
}
};
}
@NotNull
public JComponent getPreferredFocusedComponent() {
return mySampleText;
}
@NotNull
public JPanel getRootPanel() {
return myRootPanel;
}
private void updateBalloon() {
boolean correct = false;
PsiFile file = myParams.first;
PsiLanguageInjectionHost host = InjectedLanguageUtil.findInjectionHost(file);
PsiLanguageInjectionHost host = InjectedLanguageUtil.findInjectionHost(myRegexpFile);
int flags = 0;
if (host != null) {
for (RegExpModifierProvider provider : RegExpModifierProvider.EP.getExtensions()) {
flags = provider.getFlags(host, file);
flags = provider.getFlags(host, myRegexpFile);
if (flags > 0) break;
}
}
@@ -178,9 +155,6 @@ public class CheckRegExpForm {
JBColor color2 = new JBColor(new Color(255, 177, 160), new Color(110, 43, 40));
mySampleText.setBackground(correct ? color1 : color2);
myMessage.setText(correct ? "Matches!" : "no match");
BalloonImpl balloon = (BalloonImpl)myRef.get();
if (balloon != null && balloon.isDisposed()) {
balloon.revalidate();
}
myRootPanel.revalidate();
}
}
@@ -20,10 +20,8 @@ import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
@@ -55,11 +53,11 @@ public class CheckRegExpIntentionAction extends QuickEditAction implements Icona
}
@Override
protected JComponent createBalloonComponent(PsiFile file, final Ref<Balloon> ref) {
protected JComponent createBalloonComponent(@NotNull PsiFile file) {
final Project project = file.getProject();
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document != null) {
return new CheckRegExpForm(Pair.create(file, ref)).getRootPanel();
return new CheckRegExpForm(file).getRootPanel();
}
return null;
}
@@ -25,7 +25,10 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
@@ -138,7 +141,7 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
}
@Nullable
protected JComponent createBalloonComponent(PsiFile file, Ref<Balloon> ref) {
protected JComponent createBalloonComponent(@NotNull PsiFile file) {
return null;
}
@@ -150,22 +150,23 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
if (event.getEditor().getDocument() != myNewDocument) return;
myEditorCount ++;
final EditorActionHandler editorEscape = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ESCAPE);
new AnAction() {
@Override
public void update(AnActionEvent e) {
Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
e.getPresentation().setEnabled(
!myAction.isShowInBalloon() &&
editor != null && LookupManager.getActiveLookup(editor) == null &&
TemplateManager.getInstance(myProject).getActiveTemplate(editor) == null &&
(editorEscape == null || !editorEscape.isEnabled(editor, e.getDataContext())));
}
if (!myAction.isShowInBalloon()) {
new AnAction() {
@Override
public void update(AnActionEvent e) {
Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
e.getPresentation().setEnabled(
editor != null && LookupManager.getActiveLookup(editor) == null &&
TemplateManager.getInstance(myProject).getActiveTemplate(editor) == null &&
(editorEscape == null || !editorEscape.isEnabled(editor, e.getDataContext())));
}
@Override
public void actionPerformed(AnActionEvent e) {
closeEditor();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, event.getEditor().getContentComponent());
@Override
public void actionPerformed(AnActionEvent e) {
closeEditor();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, event.getEditor().getContentComponent());
}
}
@Override
@@ -203,8 +204,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
public void navigate(int injectedOffset) {
if (myAction.isShowInBalloon()) {
Ref<Balloon> ref = Ref.create(null);
final JComponent component = myAction.createBalloonComponent(myNewFile, ref);
final JComponent component = myAction.createBalloonComponent(myNewFile);
if (component != null) {
final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(component)
.setShadow(true)
@@ -214,7 +214,12 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
.setHideOnAction(false)
.setFillColor(UIUtil.getControlColor())
.createBalloon();
ref.set(balloon);
new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
balloon.hide();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, component);
Disposer.register(myNewFile.getProject(), balloon);
final Balloon.Position position = QuickEditAction.getBalloonPosition(myEditor);
RelativePoint point = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);