diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java index ec8ab5a00333..f8269dcd498b 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java @@ -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> myParams; + private final PsiFile myRegexpFile; private EditorTextField mySampleText; //TODO[kb]: make it multiline private EditorTextField myRegExp; private JPanel myRootPanel; private JBLabel myMessage; - private Ref myRef; private Project myProject; - public CheckRegExpForm(Pair> 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(); } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java index 09995dcdb0ba..6da84caa56ec 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java @@ -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 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; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java index ee4c91972046..62e3bcba3a22 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java @@ -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 ref) { + protected JComponent createBalloonComponent(@NotNull PsiFile file) { return null; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index dc4bc435b0a1..2c5d8642e46d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -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 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);