diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java index 68dce61619cb..63cf2cabb1c4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java @@ -18,10 +18,10 @@ package com.intellij.compiler.impl; import com.intellij.compiler.ProblemsView; import com.intellij.icons.AllIcons; import com.intellij.ide.errorTreeView.ErrorTreeElement; +import com.intellij.ide.errorTreeView.ErrorTreeElementKind; import com.intellij.ide.errorTreeView.ErrorViewStructure; import com.intellij.ide.errorTreeView.GroupingElement; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.ide.PooledThreadExecutor; import javax.swing.*; +import java.util.EnumSet; import java.util.UUID; /** @@ -48,7 +49,8 @@ import java.util.UUID; */ public class ProblemsViewImpl extends ProblemsView{ private static final String PROBLEMS_TOOLWINDOW_ID = "Problems"; - + private static final EnumSet ALL_MESSAGE_KINDS = EnumSet.allOf(ErrorTreeElementKind.class); + private final ProblemsViewPanel myPanel; private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE); private final Icon myActiveIcon = AllIcons.Toolwindows.Problems; @@ -70,7 +72,6 @@ public class ProblemsViewImpl extends ProblemsView{ return; } final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project, true); - updateIcon(false); final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false); // todo: setup content? tw.getContentManager().addContent(content); @@ -80,6 +81,7 @@ public class ProblemsViewImpl extends ProblemsView{ tw.getContentManager().removeAllContents(true); } }); + updateIcon(); } }); } @@ -89,19 +91,16 @@ public class ProblemsViewImpl extends ProblemsView{ myViewUpdater.execute(new Runnable() { @Override public void run() { - updateIcon(!cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId)); + cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId); + updateIcon(); myPanel.reload(); } }); } - private boolean cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) { + private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) { final ErrorViewStructure structure = myPanel.getErrorViewStructure(); - ErrorTreeElement[] elements = structure.getChildElements(fromElement); - if (elements.length ==0) return true; - - boolean result = false; - for (ErrorTreeElement element : elements) { + for (ErrorTreeElement element : structure.getChildElements(fromElement)) { if (element instanceof GroupingElement) { if (scope != null) { final VirtualFile file = ((GroupingElement)element).getFile(); @@ -111,20 +110,17 @@ public class ProblemsViewImpl extends ProblemsView{ } if (!currentSessionId.equals(element.getData())) { structure.removeElement(element); - result = true; } else { - result |= cleanupChildrenRecursively(element, scope, currentSessionId); + cleanupChildrenRecursively(element, scope, currentSessionId); } } else { if (!currentSessionId.equals(element.getData())) { structure.removeElement(element); - result = true; } } } - return result; } @Override @@ -139,7 +135,7 @@ public class ProblemsViewImpl extends ProblemsView{ public void run() { final ErrorViewStructure structure = myPanel.getErrorViewStructure(); final GroupingElement group = structure.lookupGroupingElement(groupName); - if (group != null && !sessionId.equals(group.getData())) { + if (group != null && sessionId != null && !sessionId.equals(group.getData())) { structure.removeElement(group); } if (navigatable != null) { @@ -148,21 +144,24 @@ public class ProblemsViewImpl extends ProblemsView{ else { myPanel.addMessage(type, text, null, -1, -1, sessionId); } - updateIcon(true); + updateIcon(); } }); } - private void updateIcon(final boolean active) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + private void updateIcon() { + UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID); - if (tw != null) { - tw.setIcon(active ? myActiveIcon : myPassiveIcon); + if (!myProject.isDisposed()) { + final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID); + if (tw != null) { + final boolean active = myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS); + tw.setIcon(active ? myActiveIcon : myPassiveIcon); + } } } - }, myProject.getDisposed()); + }); } @Override diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java index 618774541686..393b85f1424b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java @@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project; public class ProblemsViewPanel extends NewErrorTreeViewPanel { public ProblemsViewPanel(Project project) { - super(project, null, false, true, null); + super(project, "reference.problems.tool.window", false, true, null); myTree.getEmptyText().setText("No compilation problems found"); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java index 1ed84cda2c7f..a22242f4093a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java @@ -46,7 +46,9 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable { }); myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0); - myPanel.add(new JLabel(ProjectBundle.message("module.module.language.level")), + JLabel label = new JLabel(ProjectBundle.message("module.module.language.level")); + label.setLabelFor(myLanguageLevelCombo); + myPanel.add(label, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(12, 6, 12, 0), 0, 0)); myPanel.add(myLanguageLevelCombo, new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0)); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java index e7c1e5b955a9..87867565f63a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java @@ -27,6 +27,8 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JdkVersionUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiFile; @@ -96,6 +98,7 @@ public class IncreaseLanguageLevelFix implements IntentionAction { } else { LanguageLevelProjectExtension.getInstance(project).setLanguageLevel(myLevel); + ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.INSTANCE, false, true); } } diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java b/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java new file mode 100644 index 000000000000..27baddcd3220 --- /dev/null +++ b/platform/analysis-api/src/com/intellij/codeInspection/InjectionAwareSuppressQuickFix.java @@ -0,0 +1,18 @@ +package com.intellij.codeInspection; + +import com.intellij.psi.PsiElement; +import com.intellij.util.ThreeState; + +/** + * This kind of suppression fix allows to clients to specify whether the fix should + * be invoked on injected elements or on elements of host files. + *

+ * By default suppression fixes on injected elements are able to make suppression inside injection only. + * Whereas implementation of this interface will be provided for suppressing inside injection and in injection host. + * See {@link InspectionProfileEntry#getBatchSuppressActions(PsiElement)} for details. + */ +public interface InjectionAwareSuppressQuickFix extends SuppressQuickFix { + ThreeState isShouldBeAppliedToInjectionHost(); + + void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost); +} diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java index af1e65c67598..886d02aa55a2 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java @@ -17,6 +17,7 @@ package com.intellij.codeInspection; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.lang.Language; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; @@ -24,8 +25,10 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.util.ResourceUtil; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.SerializationFilter; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -44,14 +47,16 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; /** * @author anna * @since 28-Nov-2005 */ -@SuppressWarnings("JavadocReference") -public abstract class InspectionProfileEntry implements BatchSuppressableTool{ +public abstract class InspectionProfileEntry implements BatchSuppressableTool { public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name"); private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry"); @@ -93,22 +98,52 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ Set fixes = new THashSet(new TObjectHashingStrategy() { @Override public int computeHashCode(SuppressQuickFix object) { - return object.getName().hashCode(); + int result = object instanceof InjectionAwareSuppressQuickFix + ? ((InjectionAwareSuppressQuickFix)object).isShouldBeAppliedToInjectionHost().hashCode() + : 0; + return 31 * result + object.getName().hashCode(); } @Override public boolean equals(SuppressQuickFix o1, SuppressQuickFix o2) { + if (o1 instanceof InjectionAwareSuppressQuickFix && o2 instanceof InjectionAwareSuppressQuickFix) { + if (((InjectionAwareSuppressQuickFix)o1).isShouldBeAppliedToInjectionHost() != ((InjectionAwareSuppressQuickFix)o2).isShouldBeAppliedToInjectionHost()) { + return false; + } + } return o1.getName().equals(o2.getName()); } }); + Set suppressors = getSuppressors(element); + final PsiLanguageInjectionHost injectionHost = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); + if (injectionHost != null) { + Set injectionHostSuppressors = getSuppressors(injectionHost); + for (InspectionSuppressor suppressor : injectionHostSuppressors) { + addAllSuppressActions(fixes, injectionHost, suppressor, ThreeState.YES, getShortName()); + } + } + for (InspectionSuppressor suppressor : suppressors) { - SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName()); - fixes.addAll(Arrays.asList(actions)); + addAllSuppressActions(fixes, element, suppressor, injectionHost != null ? ThreeState.NO : ThreeState.UNSURE, getShortName()); } return fixes.toArray(new SuppressQuickFix[fixes.size()]); } + private static void addAllSuppressActions(Set fixes, + PsiElement element, + InspectionSuppressor suppressor, + ThreeState appliedToInjectionHost, + String toolShortName) { + final SuppressQuickFix[] actions = suppressor.getSuppressActions(element, toolShortName); + for (SuppressQuickFix action : actions) { + if (action instanceof InjectionAwareSuppressQuickFix) { + ((InjectionAwareSuppressQuickFix)action).setShouldBeAppliedToInjectionHost(appliedToInjectionHost); + } + fixes.add(action); + } + } + private boolean isSuppressed(@NotNull String toolId, @NotNull InspectionSuppressor suppressor, @NotNull PsiElement element) { @@ -132,7 +167,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor); return suppressors; } - return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.emptySet(); + return elementLanguageSuppressor != null + ? Collections.singleton(elementLanguageSuppressor) + : Collections.emptySet(); } public void cleanup(Project project) { @@ -148,9 +185,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ protected volatile DefaultNameProvider myNameProvider = null; /** - * @see com.intellij.codeInspection.InspectionEP#groupDisplayName - * @see com.intellij.codeInspection.InspectionEP#groupKey - * @see com.intellij.codeInspection.InspectionEP#groupBundle + * @see InspectionEP#groupDisplayName + * @see InspectionEP#groupKey + * @see InspectionEP#groupBundle */ @Nls @NotNull @@ -166,7 +203,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ } /** - * @see com.intellij.codeInspection.InspectionEP#groupPath + * @see InspectionEP#groupPath */ @NotNull public String[] getGroupPath() { @@ -178,9 +215,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ } /** - * @see com.intellij.codeInspection.InspectionEP#displayName - * @see com.intellij.codeInspection.InspectionEP#key - * @see com.intellij.codeInspection.InspectionEP#bundle + * @see InspectionEP#displayName + * @see InspectionEP#key + * @see InspectionEP#bundle */ @Nls @NotNull @@ -198,7 +235,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#shortName + * @see InspectionEP#shortName */ @NonNls @NotNull @@ -214,13 +251,13 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ @NotNull public static String getShortName(@NotNull String className) { - return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"),"InspectionBase"); + return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"), "InspectionBase"); } /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#level + * @see InspectionEP#level */ @NotNull public HighlightDisplayLevel getDefaultLevel() { @@ -230,7 +267,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * DO NOT OVERRIDE this method. * - * @see com.intellij.codeInspection.InspectionEP#enabledByDefault + * @see InspectionEP#enabledByDefault */ public boolean isEnabledByDefault() { return false; @@ -238,6 +275,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ /** * This method is called each time UI is shown. + * * @return null if no UI options required. */ @Nullable @@ -348,7 +386,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ * Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation. * * @param project to be associated with this entry - * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP} + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectOpened(@NotNull Project project) { } @@ -357,7 +395,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ * Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion. * * @param project to be disassociated from this entry - * @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP} + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectClosed(@NotNull Project project) { } @@ -411,7 +449,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{ if (descriptionUrl == null) return null; return ResourceUtil.loadText(descriptionUrl); } - catch (IOException ignored) { } + catch (IOException ignored) { + } return null; } diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java index 7a8c3e3c6cde..6bc8511bd5b5 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/AbstractBatchSuppressByNoInspectionCommentFix.java @@ -17,9 +17,9 @@ package com.intellij.codeInsight.daemon.impl.actions; import com.intellij.codeInsight.FileModificationService; +import com.intellij.codeInspection.InjectionAwareSuppressQuickFix; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.SuppressQuickFix; import com.intellij.codeInspection.SuppressionUtil; import com.intellij.icons.AllIcons; import com.intellij.lang.Language; @@ -32,6 +32,7 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,9 +44,10 @@ import java.util.List; * @author Roman.Chernyatchik * @date Aug 13, 2009 */ -public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements SuppressQuickFix, Iconable { +public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements InjectionAwareSuppressQuickFix, Iconable { @NotNull protected final String myID; private final boolean myReplaceOtherSuppressionIds; + private ThreeState myShouldBeAppliedToInjectionHost = ThreeState.UNSURE; @Nullable public abstract PsiElement getContainer(final PsiElement context); @@ -60,6 +62,15 @@ public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements S myReplaceOtherSuppressionIds = replaceOtherSuppressionIds; } + public void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost) { + myShouldBeAppliedToInjectionHost = shouldBeAppliedToInjectionHost; + } + + @Override + public ThreeState isShouldBeAppliedToInjectionHost() { + return myShouldBeAppliedToInjectionHost; + } + @NotNull @Override public String getName() { diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java index 3fc800e87879..d92101c386fb 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -59,9 +60,15 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { } } + public ThreeState isShouldBeAppliedToInjectionHost() { + return myFix instanceof InjectionAwareSuppressQuickFix + ? ((InjectionAwareSuppressQuickFix)myFix).isShouldBeAppliedToInjectionHost() + : ThreeState.UNSURE; + } + public PsiElement getContainer(PsiElement element) { return myFix instanceof AbstractBatchSuppressByNoInspectionCommentFix - ? ((AbstractBatchSuppressByNoInspectionCommentFix )myFix).getContainer(element) : null; + ? ((AbstractBatchSuppressByNoInspectionCommentFix)myFix).getContainer(element) : null; } @Override @@ -72,7 +79,7 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction { @NotNull @Override public String getText() { - return myFix.getName(); + return myFix.getName() + (isShouldBeAppliedToInjectionHost() == ThreeState.NO ? " in injection" : ""); } @NotNull diff --git a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java index 8a355d263a07..552d7563a2f2 100644 --- a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java +++ b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java @@ -143,7 +143,7 @@ public class EnvVariablesTable extends ListTableWithButtons public void actionPerformed(@NotNull AnActionEvent e) { stopEditing(); StringBuilder sb = new StringBuilder(); - List variables = getEnvironmentVariables(); + List variables = getSelection(); for (EnvironmentVariable environmentVariable : variables) { if (environmentVariable.getIsPredefined() || isEmpty(environmentVariable)) continue; if (sb.length() > 0) sb.append('\n'); @@ -152,10 +152,16 @@ public class EnvVariablesTable extends ListTableWithButtons } CopyPasteManager.getInstance().setContents(new StringSelection(sb.toString())); } + + @Override + public boolean isEnabled() { + return super.isEnabled() && !getSelection().isEmpty(); + } }; AnActionButton pasteButton = new AnActionButton(ActionsBundle.message("action.EditorPaste.text"), AllIcons.Actions.Menu_paste) { @Override public void actionPerformed(@NotNull AnActionEvent e) { + removeSelected(); stopEditing(); String content = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor); if (content == null || !content.contains("=")) return; @@ -172,13 +178,7 @@ public class EnvVariablesTable extends ListTableWithButtons StringUtil.unescapeStringCharacters(line.substring(pos + 1)), false)); } - List variables = - new ArrayList(ContainerUtil.filter(getEnvironmentVariables(), new Condition() { - @Override - public boolean value(EnvironmentVariable variable) { - return variable.getIsPredefined(); - } - })); + List variables = new ArrayList(getEnvironmentVariables()); variables.addAll(parsed); setValues(variables); } diff --git a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java index 71ed67719cb9..5ea5a2ae5ac7 100644 --- a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java +++ b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java @@ -16,6 +16,7 @@ package com.intellij.execution.util; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.Condition; import com.intellij.ui.*; import com.intellij.ui.table.TableView; import com.intellij.util.containers.ContainerUtil; @@ -30,6 +31,7 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Observable; @@ -110,31 +112,19 @@ public abstract class ListTableWithButtons extends Observable { }).setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { - myTableView.stopEditing(); - setModified(); - T selected = getSelection(); - if (selected != null) { - int selectedIndex = myElements.indexOf(selected); - myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true)); - myElements.remove(selected); - myTableView.getTableViewModel().setItems(myElements); - - int prev = selectedIndex - 1; - if (prev >= 0) { - myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev); - } - else if (selectedIndex < myElements.size()) { - myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); - } - } + removeSelected(); } }).disableUpDownActions().addExtraActions(createExtraActions()).createPanel(); ToolbarDecorator.findRemoveButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { - T selection = getSelection(); - return selection != null && myIsEnabled && canDeleteElement(selection); + List selection = getSelection(); + if (selection.isEmpty() || !myIsEnabled) return false; + for (T t : selection) { + if (!canDeleteElement(t)) return false; + } + return true; } }); ToolbarDecorator.findAddButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() { @@ -146,7 +136,33 @@ public abstract class ListTableWithButtons extends Observable { myActionsPanel = decorator.getActionsPanel(); - myTableView.getComponent().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTableView.getComponent().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + } + + protected void removeSelected() { + List selected = getSelection(); + if (!selected.isEmpty()) { + myTableView.stopEditing(); + setModified(); + int selectedIndex = myTableView.getSelectionModel().getLeadSelectionIndex(); + myTableView.scrollRectToVisible(myTableView.getCellRect(selectedIndex, 0, true)); + selected = ContainerUtil.filter(selected, new Condition() { + @Override + public boolean value(T t) { + return canDeleteElement(t); + } + }); + myElements.removeAll(selected); + myTableView.getTableViewModel().setItems(myElements); + + int prev = selectedIndex - 1; + if (prev >= 0) { + myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev); + } + else if (selectedIndex < myElements.size()) { + myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); + } + } } @NotNull @@ -197,7 +213,9 @@ public abstract class ListTableWithButtons extends Observable { } protected void editSelection(int column) { - int row = myElements.indexOf(getSelection()); + List selection = getSelection(); + if (selection.size() != 1) return; + int row = myElements.indexOf(selection.get(0)); if (row != -1) { TableUtil.editCellAt(myTableView, row, column); } @@ -213,13 +231,18 @@ public abstract class ListTableWithButtons extends Observable { } - protected T getSelection() { - int selIndex = myTableView.getComponent().getSelectionModel().getMinSelectionIndex(); - if (selIndex < 0) { - return null; + @NotNull + protected List getSelection() { + int[] selection = myTableView.getComponent().getSelectedRows(); + if (selection.length == 0) { + return Collections.emptyList(); } else { - return myElements.get(selIndex); + List result = new ArrayList(selection.length); + for (int row : selection) { + result.add(myElements.get(row)); + } + return result; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java index d71f60589150..436356065f2c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java @@ -28,10 +28,14 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable; +import com.intellij.codeInsight.unwrap.ScopeHighlighter; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.icons.AllIcons; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -52,7 +56,9 @@ import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.refactoring.BaseRefactoringIntentionAction; import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; @@ -61,6 +67,7 @@ import com.intellij.ui.RowIcon; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Alarm; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.NotNull; @@ -69,11 +76,14 @@ import org.jetbrains.annotations.TestOnly; import javax.swing.*; import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Collections; import java.util.List; /** @@ -441,12 +451,52 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll Disposer.dispose(myPopup); } myPopup = JBPopupFactory.getInstance().createListPopup(step); + + final PsiFile injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(myFile, myEditor.getCaretModel().getOffset()); + final Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile); + + final ScopeHighlighter highlighter = new ScopeHighlighter(myEditor); + final ScopeHighlighter injectionHighlighter = new ScopeHighlighter(injectedEditor); + myPopup.addListener(new JBPopupListener.Adapter() { @Override public void onClosed(LightweightWindowEvent event) { + highlighter.dropHighlight(); + injectionHighlighter.dropHighlight(); myPopupShown = false; } }); + myPopup.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + final Object source = e.getSource(); + highlighter.dropHighlight(); + injectionHighlighter.dropHighlight(); + + if (source instanceof DataProvider) { + final Object selectedItem = PlatformDataKeys.SELECTED_ITEM.getData((DataProvider)source); + if (selectedItem instanceof IntentionActionWithTextCaching) { + final IntentionAction action = ((IntentionActionWithTextCaching)selectedItem).getAction(); + if (action instanceof SuppressIntentionActionFromFix) { + if (injectedFile != null && ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost() == ThreeState.NO) { + final PsiElement at = injectedFile.findElementAt(injectedEditor.getCaretModel().getOffset()); + final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at); + if (container != null) { + injectionHighlighter.highlight(container, Collections.singletonList(container)); + } + } + else { + final PsiElement at = myFile.findElementAt(myEditor.getCaretModel().getOffset()); + final PsiElement container = ((SuppressIntentionActionFromFix)action).getContainer(at); + if (container != null) { + highlighter.highlight(container, Collections.singletonList(container)); + } + } + } + } + } + } + }); if (myEditor.isOneLineMode()) { // hide popup on combobox popup show diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 0700b6e1e1b2..491508e2c7a8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -27,6 +27,7 @@ import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInspection.IntentionWrapper; import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; @@ -39,6 +40,7 @@ import com.intellij.openapi.util.Iconable; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; @@ -321,6 +323,11 @@ class IntentionListStep implements ListPopupStep if (a instanceof LowPriorityAction) { return group - 3; } + if (a instanceof SuppressIntentionActionFromFix) { + if (((SuppressIntentionActionFromFix)a).isShouldBeAppliedToInjectionHost() == ThreeState.NO) { + return group - 1; + } + } if (a instanceof QuickFixWrapper) { final LocalQuickFix quickFix = ((QuickFixWrapper)a).getFix(); if (quickFix instanceof HighPriorityAction) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index 8ddebd7c383f..31c1ecd533d1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -27,6 +27,7 @@ import com.intellij.codeInsight.lookup.LookupEx; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.FeatureUsageTrackerImpl; import com.intellij.injected.editor.EditorWindow; @@ -45,6 +46,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PairProcessor; +import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -107,6 +109,16 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { private static boolean isAvailableHere(Editor editor, PsiFile psiFile, PsiElement psiElement, boolean inProject, IntentionAction action) { try { Project project = psiFile.getProject(); + if (action instanceof SuppressIntentionActionFromFix) { + final ThreeState shouldBeAppliedToInjectionHost = ((SuppressIntentionActionFromFix)action).isShouldBeAppliedToInjectionHost(); + if (editor instanceof EditorWindow && shouldBeAppliedToInjectionHost == ThreeState.YES) { + return false; + } + if (!(editor instanceof EditorWindow) && shouldBeAppliedToInjectionHost == ThreeState.NO) { + return false; + } + } + if (action instanceof PsiElementBaseIntentionAction) { if (!inProject || psiElement == null || !((PsiElementBaseIntentionAction)action).isAvailable(project, editor, psiElement)) return false; } diff --git a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java index 7a65062fe33c..78451fe4580e 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java @@ -30,9 +30,9 @@ import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -58,7 +58,7 @@ import java.util.Map; /** * @author gregsh */ -public class RunIdeConsoleAction extends ActionGroup implements DumbAware { +public class RunIdeConsoleAction extends DumbAwareAction { private static final String DEFAULT_FILE_NAME = "ide-scripting"; private static final Key> CONSOLE_VIEW_KEY = Key.create("CONSOLE_VIEW_KEY"); @@ -84,26 +84,23 @@ public class RunIdeConsoleAction extends ActionGroup implements DumbAware { runConsole(e, ourEngines.values().iterator().next()); } else { - super.actionPerformed(e); - } - } - - @NotNull - @Override - public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null) return EMPTY_ARRAY; - return ContainerUtil.map2Array(ourEngines.values(), AnAction.class, new NotNullFunction() { - @NotNull - @Override - public AnAction fun(final ScriptEngineFactory engine) { - return new AnAction(engine.getLanguageName()) { + DefaultActionGroup actions = new DefaultActionGroup( + ContainerUtil.map(ourEngines.values(), new NotNullFunction() { + @NotNull @Override - public void actionPerformed(@NotNull AnActionEvent e) { - runConsole(e, engine); + public AnAction fun(final ScriptEngineFactory engine) { + return new AnAction(engine.getLanguageName()) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + runConsole(e, engine); + } + }; } - }; - } - }); + }) + ); + JBPopupFactory.getInstance().createActionGroupPopup("Script Engine", actions, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false). + showInBestPositionFor(e.getDataContext()); + } } protected void runConsole(@NotNull AnActionEvent e, @NotNull ScriptEngineFactory engine) { diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java index 937fee52279b..2f813722b91d 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchRootType.java @@ -69,7 +69,7 @@ public final class ScratchRootType extends RootType { } } - private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile, InternalFileType { + private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile { MyFileType() { super(PlainTextLanguage.INSTANCE); diff --git a/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java b/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java index b964f200fc41..e96b5baa092d 100644 --- a/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java +++ b/platform/platform-impl/src/com/intellij/ide/errorTreeView/ErrorViewStructure.java @@ -69,6 +69,30 @@ public class ErrorViewStructure extends AbstractTreeStructure { return myRoot; } + public boolean hasMessages(@NotNull Set kinds) { + synchronized (myLock) { + for (Map.Entry> entry : mySimpleMessages.entrySet()) { + if (kinds.contains(entry.getKey())) { + final List messages = entry.getValue(); + if (messages != null && !messages.isEmpty()) { + return true; + } + } + } + for (Map.Entry> entry : myGroupNameToMessagesMap.entrySet()) { + final List messages = entry.getValue(); + if (messages != null && !messages.isEmpty()) { + for (NavigatableMessageElement message : messages) { + if (kinds.contains(message.getKind())) { + return true; + } + } + } + } + } + return false; + } + @Override public ErrorTreeElement[] getChildElements(Object element) { if (element == myRoot) { diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 89e1b18c6bb2..7cc7305fe3b0 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -267,6 +267,13 @@ public abstract class AbstractExpandableItemsHandler - + - + diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties index b971ee325fec..4b31b4aaca45 100644 --- a/platform/projectModel-impl/src/messages/ProjectBundle.properties +++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties @@ -114,7 +114,7 @@ jdk.combo.box.project.item= jdk.combo.box.none.item= jdk.combo.box.invalid.item={0} [Invalid] module.libraries.target.jdk.project.radio=&Project SDK:
This SDK is default for all project modules.
\ - A module specific SDK can be configured for each of the modules as required + A module specific SDK can be configured for each of the modules as required. module.libraries.target.jdk.module.radio=&Module SDK: module.libraries.target.jdk.select.title=Select Project SDK module.libraries.javadoc.url.button=Specify Documentation &URL... @@ -263,11 +263,11 @@ project.inherit.compile.output.path=Inherit project compile output path project.module.compile.output.path=Use module compile output path project.compiler.output=Project compiler output:
This path is used to store all project compilation results.
\ A directory corresponding to each module is created under this path.
This directory contains two subdirectories: Production and Test for production code and test sources, respectively.
\ - A module specific compiler output path can be configured for each of the modules as required + A module specific compiler output path can be configured for each of the modules as required. find.usages.action.text=Find Usages dependencies.used.in.popup.title=Used in project.language.level=Project language level:
This language level is default for all project modules.
\ - A module specific language level can be configured for each of the modules as required + A module specific language level can be configured for each of the modules as required. classpath.panel.analyze=Analyze classpath.panel.navigate.action.text=Navigate output.tab.title=Output diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 9f3fbc17f8e8..42f40fbfd265 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1701,14 +1701,23 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig descriptors.addAll(intentions.inspectionFixesToShow); descriptors.addAll(intentions.guttersToShow); - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + final int fileOffset = editor.getCaretModel().getOffset(); + PsiElement hostElement = file.getViewProvider().findElementAt(fileOffset, file.getLanguage()); + PsiElement injectedElement = InjectedLanguageUtil.findElementAtNoCommit(file, fileOffset); + + PsiFile injectedFile = injectedElement != null ? injectedElement.getContainingFile() : null; + Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile); + List result = new ArrayList(); List infos = DaemonCodeAnalyzerEx.getInstanceEx(file.getProject()).getFileLevelHighlights(file.getProject(), file); for (HighlightInfo info : infos) { for (Pair pair : info.quickFixActionRanges) { HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first; - if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) { + final IntentionAction action = actionInGroup.getAction(); + + if (ShowIntentionActionsHandler.availableFor(file, editor, action) + || (injectedElement != null && hostElement != injectedElement && ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { descriptors.add(actionInGroup); } } @@ -1717,11 +1726,25 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig // add all intention options for simplicity for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) { result.add(descriptor.getAction()); - List options = descriptor.getOptions(element,editor); - if (options != null) { - for (IntentionAction option : options) { - if (option.isAvailable(file.getProject(), editor, file)) { - result.add(option); + + if (injectedElement != null && injectedElement != hostElement) { + List options = descriptor.getOptions(injectedElement, injectedEditor); + if (options != null) { + for (IntentionAction option : options) { + if (ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, option)) { + result.add(option); + } + } + } + } + + if (hostElement != null) { + List options = descriptor.getOptions(hostElement, editor); + if (options != null) { + for (IntentionAction option : options) { + if (ShowIntentionActionsHandler.availableFor(file, editor, option)) { + result.add(option); + } } } } diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java index 9480a02ab81e..6ec4a1ef09a0 100644 --- a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java +++ b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java @@ -219,6 +219,8 @@ public class RemoteUtil { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { + if ("equals".equals(method.getName())) return proxy == args[0]; + if ("hashCode".equals(method.getName())) return hashCode(); return method.invoke(myRemote, args); } else { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index a3d99c33228c..a91983706af7 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -47,7 +47,7 @@ public class JiraIntegrationTest extends TaskManagerTestCase { /** * JIRA 4.4.5, REST API 2.0.alpha1 */ - @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://trackers-tests.labs.intellij.net:8014"; + @NonNls private static final String JIRA_4_TEST_SERVER_URL = "http://idea-qa-task-2.labs.intellij.net:8014"; /** * JIRA 5.0.6, REST API 2.0 */ diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java index 24fd7faaeee1..d23114a1d243 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/EmmetEditPointUtil.java @@ -17,59 +17,74 @@ package com.intellij.codeInsight.template.emmet.actions; import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.*; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlText; import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.ObjectUtils; /** * @author Dennis.Ushakov */ public class EmmetEditPointUtil { - public static void moveForward(Editor editor, PsiFile file) { + public static void moveForward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), 1); } - public static void moveBackward(Editor editor, PsiFile file) { + public static void moveBackward(final Editor editor, final PsiFile file) { if (!isApplicableFile(file)) return; moveToNextPoint(editor, file, editor.getCaretModel().getOffset(), -1); } private static void moveToNextPoint(Editor editor, PsiFile file, int offset, int inc) { final Document doc = editor.getDocument(); + final TemplateLanguageFileViewProvider provider = ObjectUtils.tryCast(file.getViewProvider(), TemplateLanguageFileViewProvider.class); + final Language additionalLanguage = provider != null ? provider.getTemplateDataLanguage() : null; PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc); for (int i = offset + inc; i < doc.getTextLength() && i >= 0; i += inc) { PsiElement current = InjectedLanguageUtil.findElementAtNoCommit(file, i); - if (current == null) continue; - - if (current.getParent() instanceof XmlText) { - final int line = doc.getLineNumber(i); - final int lineStart = doc.getLineStartOffset(line); - final int lineEnd = doc.getLineEndOffset(line); - if (lineEnd == offset) continue; - - final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd); - if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) { - return; - } - } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) { - return; + if (checkAndMove(editor, doc, i, current)) return; + if (additionalLanguage != null) { + current = provider.findElementAt(i, additionalLanguage); + if (checkAndMove(editor, doc, i, current)) return; } } } + private static boolean checkAndMove(Editor editor, Document doc, int offset, PsiElement current) { + if (current == null) return false; + if (current.getParent() instanceof XmlText) { + final int line = doc.getLineNumber(offset); + final int lineStart = doc.getLineStartOffset(line); + final int lineEnd = doc.getLineEndOffset(line); + + final CharSequence text = doc.getCharsSequence().subSequence(lineStart, lineEnd); + if (StringUtil.isEmptyOrSpaces(text) && moveCaret(editor, current, lineEnd)) { + return true; + } + } else if (isEmptyEditPoint(current) && moveCaret(editor, current, current.getTextRange().getStartOffset())) { + return true; + } + return false; + } + private static boolean moveCaret(Editor editor, PsiElement current, int offset) { editor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, current.getContainingFile()); - if (editor.getCaretModel().getOffset() == offset) return false; - editor.getCaretModel().moveToOffset(offset); + final CaretModel caretModel = editor.getCaretModel(); + if (caretModel.getOffset() == offset) return false; + + caretModel.moveToOffset(offset); + final Caret caret = caretModel.getCurrentCaret(); + ScrollingModel scrollingModel = editor.getScrollingModel(); + if (caret == caretModel.getPrimaryCaret()) { + scrollingModel.scrollToCaret(ScrollType.RELATIVE); + } return true; } @@ -89,7 +104,7 @@ public class EmmetEditPointUtil { static boolean isApplicableFile(PsiFile file) { if (file == null) return false; for (Language language : file.getViewProvider().getLanguages()) { - if (language.isKindOf(XMLLanguage.INSTANCE)) return true; + if (language.isKindOf(XMLLanguage.INSTANCE) || "JavaScript".equals(language.getID())) return true; } return false; } diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java index f6c66a88931f..840126aafa19 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/actions/GoToEditPointAction.java @@ -15,45 +15,57 @@ */ package com.intellij.codeInsight.template.emmet.actions; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import org.jetbrains.annotations.Nullable; /** * @author Dennis.Ushakov */ -public abstract class GoToEditPointAction extends DumbAwareAction { +public abstract class GoToEditPointAction extends EditorAction implements DumbAware { + protected GoToEditPointAction(EditorActionHandler defaultHandler) { + super(defaultHandler); + } + @Override - public void update(AnActionEvent e) { - final Editor editor = getEditor(e); - final PsiFile file = getFile(e); - final boolean isApplicable = editor != null && EmmetEditPointUtil.isApplicableFile(file); - e.getPresentation().setEnabledAndVisible(isApplicable); + public void update(Editor editor, Presentation presentation, DataContext dataContext) { + super.update(editor, presentation, dataContext); + final PsiFile file = getFile(dataContext); + if (!EmmetEditPointUtil.isApplicableFile(file)) { + presentation.setEnabledAndVisible(false); + } } - private static PsiFile getFile(AnActionEvent e) { - return CommonDataKeys.PSI_FILE.getData(e.getDataContext()); - } - - private static Editor getEditor(AnActionEvent e) { - final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); - return editor != null ? InjectedLanguageUtil.getTopLevelEditor(editor) : null; + private static PsiFile getFile(DataContext context) { + return CommonDataKeys.PSI_FILE.getData(context); } public static class Forward extends GoToEditPointAction { - @Override - public void actionPerformed(AnActionEvent e) { - EmmetEditPointUtil.moveForward(getEditor(e), getFile(e)); + public Forward() { + super(new EditorActionHandler(true) { + @Override + protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) { + EmmetEditPointUtil.moveForward(editor, getFile(dataContext)); + } + }); } } public static class Backward extends GoToEditPointAction { - @Override - public void actionPerformed(AnActionEvent e) { - EmmetEditPointUtil.moveBackward(getEditor(e), getFile(e)); + public Backward() { + super(new EditorActionHandler(true) { + @Override + protected void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) { + EmmetEditPointUtil.moveBackward(editor, getFile(dataContext)); + } + }); } } }