mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -770,7 +770,7 @@ def layoutJps(String home, String targetDir, String buildNumber, Closure additio
|
||||
include(name: "jdom.jar")
|
||||
include(name: "jna.jar")
|
||||
include(name: "trove4j.jar")
|
||||
include(name: "asm4-all.jar")
|
||||
include(name: "asm-all.jar")
|
||||
include(name: "nanoxml-*.jar")
|
||||
include(name: "protobuf-*.jar")
|
||||
include(name: "cli-parser-*.jar")
|
||||
|
||||
@@ -226,6 +226,7 @@ binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
|
||||
binding.setVariable("commonJvmArgs", {
|
||||
return [
|
||||
"-ea",
|
||||
"-server",
|
||||
"-Didea.home.path=$home",
|
||||
"-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
|
||||
@@ -80,7 +80,8 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
//noinspection unchecked
|
||||
final List<SmartStepTarget> targets = new OrderedSet<SmartStepTarget>();
|
||||
|
||||
final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(element.getTextOffset()), doc.getLineNumber(element.getTextOffset() + element.getTextLength()));
|
||||
TextRange textRange = element.getTextRange();
|
||||
final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(textRange.getStartOffset()), doc.getLineNumber(textRange.getEndOffset()));
|
||||
|
||||
final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() {
|
||||
final Stack<PsiMethod> myContextStack = new Stack<PsiMethod>();
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.impl.EditorTextProvider;
|
||||
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -60,6 +59,11 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator {
|
||||
@NotNull final XEvaluationCallback callback,
|
||||
@Nullable XSourcePosition expressionPosition) {
|
||||
myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) {
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadAction() {
|
||||
WatchItemDescriptor descriptor = new WatchItemDescriptor(myDebugProcess.getProject(), TextWithImportsImpl.fromXExpression(
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
@@ -546,7 +547,12 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
|
||||
}
|
||||
|
||||
static String constructLabelText(final String keylabel, final String valueLabel) {
|
||||
return keylabel + " -> " + valueLabel;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\"').append(keylabel).append("\" -> ");
|
||||
if (!StringUtil.isEmpty(valueLabel)) {
|
||||
sb.append('\"').append(valueLabel).append('\"');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getDescriptorLabel(final ValueDescriptorImpl keyDescriptor) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,13 +18,19 @@ package com.intellij.ide.actions;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
|
||||
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
public class ShowStructureSettingsAction extends AnAction implements DumbAware {
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
@@ -33,6 +39,23 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
|
||||
project = ProjectManager.getInstance().getDefaultProject();
|
||||
}
|
||||
|
||||
ShowSettingsUtil.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
new SingleConfigurableEditor(project, ProjectStructureConfigurable.getInstance(project), OptionsEditorDialog.DIMENSION_KEY) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Border createContentPaneBorder() {
|
||||
return new EmptyBorder(0,0,0,0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createSouthPanel() {
|
||||
return null;
|
||||
}
|
||||
}.show();
|
||||
} else {
|
||||
ShowSettingsUtil
|
||||
.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.intellij.ide.util.newProjectWizard.StepSequence;
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -46,6 +47,7 @@ public class NewProjectWizard extends AbstractProjectWizard {
|
||||
protected void init(@NotNull ModulesProvider modulesProvider) {
|
||||
myWizardContext.setNewWizard(true);
|
||||
ProjectTypeStep projectTypeStep = new ProjectTypeStep(myWizardContext, this, modulesProvider);
|
||||
Disposer.register(getDisposable(), projectTypeStep);
|
||||
mySequence.addCommonStep(projectTypeStep);
|
||||
ChooseTemplateStep chooseTemplateStep = new ChooseTemplateStep(myWizardContext, projectTypeStep);
|
||||
mySequence.addCommonStep(chooseTemplateStep);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryEx;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.navigation.History;
|
||||
import com.intellij.ui.navigation.Place;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
@@ -238,9 +239,10 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable {
|
||||
|
||||
createEditors(getModule());
|
||||
|
||||
JPanel northPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
myGenericSettingsPanel.add(northPanel, BorderLayout.NORTH);
|
||||
if (!Registry.is("ide.new.project.settings")) {
|
||||
JPanel northPanel = new JPanel(new GridBagLayout());
|
||||
myGenericSettingsPanel.add(northPanel, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
final JComponent component = createCenterPanel();
|
||||
myGenericSettingsPanel.add(component, BorderLayout.CENTER);
|
||||
|
||||
+19
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,11 +38,13 @@ import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactsStructureC
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.*;
|
||||
import com.intellij.openapi.ui.DetailsComponent;
|
||||
import com.intellij.openapi.ui.MasterDetailsComponent;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBSplitter;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.ui.navigation.BackAction;
|
||||
import com.intellij.ui.navigation.ForwardAction;
|
||||
@@ -67,7 +69,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
|
||||
public static final DataKey<ProjectStructureConfigurable> KEY = DataKey.create("ProjectStructureConfiguration");
|
||||
|
||||
protected final UIState myUiState = new UIState();
|
||||
private Splitter mySplitter;
|
||||
private JBSplitter mySplitter;
|
||||
private JComponent myToolbarComponent;
|
||||
@NonNls public static final String CATEGORY = "category";
|
||||
private JComponent myToFocus;
|
||||
@@ -173,8 +175,16 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
|
||||
public JComponent createComponent() {
|
||||
myComponent = new MyPanel();
|
||||
|
||||
mySplitter = new Splitter(false, .15f);
|
||||
mySplitter = new JBSplitter(false, .15f);
|
||||
mySplitter.setSplitterProportionKey("ProjectStructure.TopLevelElements");
|
||||
mySplitter.setHonorComponentsMinimumSize(true);
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
mySplitter.setDividerWidth(1);
|
||||
mySplitter.setShowDividerIcon(false);
|
||||
mySplitter.getDivider().setBackground(Gray._153.withAlpha(128));
|
||||
mySplitter.setShowDividerControls(false);
|
||||
mySplitter.setOrientation(mySplitter.getOrientation());
|
||||
}
|
||||
|
||||
initSidePanel();
|
||||
|
||||
@@ -192,7 +202,11 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarGroup, true);
|
||||
toolbar.setTargetComponent(myComponent);
|
||||
myToolbarComponent = toolbar.getComponent();
|
||||
left.add(myToolbarComponent, BorderLayout.NORTH);
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
left.setBackground(new Color(0xD2D6DD));
|
||||
} else {
|
||||
left.add(myToolbarComponent, BorderLayout.NORTH);
|
||||
}
|
||||
left.add(mySidePanel, BorderLayout.CENTER);
|
||||
|
||||
mySplitter.setFirstComponent(left);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,14 +17,17 @@ package com.intellij.openapi.roots.ui.configuration;
|
||||
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.ui.popup.ListItemDescriptor;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.navigation.History;
|
||||
import com.intellij.ui.navigation.Place;
|
||||
import com.intellij.ui.popup.list.GroupedItemsListRenderer;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
@@ -52,7 +55,10 @@ public class SidePanel extends JPanel {
|
||||
|
||||
myModel = new DefaultListModel();
|
||||
myList = new JBList(myModel);
|
||||
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
myList.setBackground(new Color(0xD2D6DD));
|
||||
myList.setBorder(new EmptyBorder(5, 0, 0, 0));
|
||||
}
|
||||
final ListItemDescriptor descriptor = new ListItemDescriptor() {
|
||||
@Override
|
||||
public String getTextFor(final Object value) {
|
||||
@@ -66,7 +72,7 @@ public class SidePanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public Icon getIconFor(final Object value) {
|
||||
return null;
|
||||
return Registry.is("ide.new.project.settings") ? EmptyIcon.create(16, 20) : null;
|
||||
//return myPlace2Presentation.get(value).getIcon();
|
||||
}
|
||||
|
||||
@@ -78,14 +84,22 @@ public class SidePanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public String getCaptionAboveOf(final Object value) {
|
||||
return myIndex2Separator.get(myPlaces.indexOf(value));
|
||||
String text = myIndex2Separator.get(myPlaces.indexOf(value));
|
||||
return text != null && Registry.is("ide.new.project.settings") ? text.toUpperCase() : text;
|
||||
}
|
||||
};
|
||||
|
||||
myList.setCellRenderer(new GroupedItemsListRenderer(descriptor));
|
||||
myList.setCellRenderer(new GroupedItemsListRenderer(descriptor) {
|
||||
{
|
||||
mySeparatorComponent.setCaptionCentered(false);
|
||||
}
|
||||
@Override
|
||||
protected Color getBackground() {
|
||||
return Registry.is("ide.new.project.settings") ? new Color(0xD2D6DD) : super.getBackground();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
add(ScrollPaneFactory.createScrollPane(myList), BorderLayout.CENTER);
|
||||
add(ScrollPaneFactory.createScrollPane(myList, Registry.is("ide.new.project.settings")), BorderLayout.CENTER);
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
myList.addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
+6
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,6 +38,8 @@ import com.intellij.openapi.ui.NamedConfigurable;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.ui.TreeSpeedSearch;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
@@ -300,7 +302,9 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i
|
||||
result.addAll(copyActions);
|
||||
result.add(Separator.getInstance());
|
||||
|
||||
result.add(new MyFindUsagesAction(myTree));
|
||||
if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
|
||||
result.add(new MyFindUsagesAction(myTree));
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
+6
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,7 +53,9 @@ import com.intellij.openapi.ui.*;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -149,7 +151,9 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
|
||||
final ArrayList<AnAction> result = super.createActions(fromPopup);
|
||||
result.add(Separator.getInstance());
|
||||
result.add(new MyGroupAction());
|
||||
addCollapseExpandActions(result);
|
||||
if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
|
||||
addCollapseExpandActions(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+14
-8
@@ -53,6 +53,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -340,6 +341,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
final Object[] variants = reference.getVariants();
|
||||
//noinspection ConstantConditions
|
||||
if (variants == null) {
|
||||
LOG.error("Reference=" + reference);
|
||||
}
|
||||
@@ -365,6 +367,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
|
||||
}
|
||||
else {
|
||||
//noinspection deprecation
|
||||
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
|
||||
usedWords.add(element.getLookupString());
|
||||
result.addElement(element);
|
||||
@@ -434,7 +437,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement,
|
||||
CompletionParameters parameters) {
|
||||
PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class);
|
||||
PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)pair.getParent();
|
||||
PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)ObjectUtils.assertNotNull(pair).getParent();
|
||||
PsiAnnotation anno = (PsiAnnotation)parameterList.getParent();
|
||||
boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement);
|
||||
PsiClass annoClass = null;
|
||||
@@ -507,7 +510,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (psiElement().withParent(psiReferenceExpression().withFirstChild(psiReferenceExpression().referencing(psiClass()))).accepts(position)) {
|
||||
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
|
||||
if (shortcut != null) {
|
||||
if (StringUtil.isNotEmpty(shortcut)) {
|
||||
return "Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods";
|
||||
}
|
||||
}
|
||||
@@ -517,7 +520,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (parameters.getCompletionType() != CompletionType.SMART && shouldSuggestSmartCompletion(parameters.getPosition())) {
|
||||
if (CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.EDITING_COMPLETION_SMARTTYPE_GENERAL)) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
|
||||
if (shortcut != null) {
|
||||
if (StringUtil.isNotEmpty(shortcut)) {
|
||||
return CompletionBundle.message("completion.smart.hint", shortcut);
|
||||
}
|
||||
}
|
||||
@@ -528,7 +531,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (psiTypes.length > 0) {
|
||||
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_TOAR)) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
|
||||
if (shortcut != null) {
|
||||
if (StringUtil.isNotEmpty(shortcut)) {
|
||||
for (final PsiType psiType : psiTypes) {
|
||||
final PsiType type = PsiUtil.extractIterableTypeParameter(psiType, false);
|
||||
if (type != null) {
|
||||
@@ -539,7 +542,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_ASLIST)) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
|
||||
if (shortcut != null) {
|
||||
if (StringUtil.isNotEmpty(shortcut)) {
|
||||
for (final PsiType psiType : psiTypes) {
|
||||
if (psiType instanceof PsiArrayType) {
|
||||
final PsiType componentType = ((PsiArrayType)psiType).getComponentType();
|
||||
@@ -553,7 +556,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
|
||||
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_CHAIN)) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
|
||||
if (shortcut != null) {
|
||||
if (StringUtil.isNotEmpty(shortcut)) {
|
||||
return CompletionBundle.message("completion.smart.chain.hint", shortcut);
|
||||
}
|
||||
}
|
||||
@@ -639,9 +642,12 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
final PsiFile file = context.getFile();
|
||||
|
||||
if (file instanceof PsiJavaFile) {
|
||||
JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
|
||||
if (context.getInvocationCount() > 0) {
|
||||
autoImport(file, context.getStartOffset() - 1, context.getEditor());
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
|
||||
}
|
||||
|
||||
autoImport(file, context.getStartOffset() - 1, context.getEditor());
|
||||
JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
|
||||
|
||||
if (context.getCompletionType() == CompletionType.BASIC) {
|
||||
if (semicolonNeeded(context.getEditor(), file, context.getStartOffset())) {
|
||||
|
||||
@@ -103,10 +103,11 @@ public class PsiTypeLookupItem extends LookupItem {
|
||||
myImportFixer.handleInsert(context, this);
|
||||
|
||||
PsiElement position = context.getFile().findElementAt(context.getStartOffset());
|
||||
assert position != null;
|
||||
int genericsStart = context.getTailOffset();
|
||||
context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context)));
|
||||
JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1);
|
||||
if (position != null) {
|
||||
int genericsStart = context.getTailOffset();
|
||||
context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context)));
|
||||
JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1);
|
||||
}
|
||||
|
||||
int tail = context.getTailOffset();
|
||||
String braces = StringUtil.repeat("[]", getBracketsCount());
|
||||
|
||||
+5
@@ -229,4 +229,9 @@ public class JavaArrangementParseInfo {
|
||||
public List<ArrangementEntryDependencyInfo> getFieldDependencyRoots() {
|
||||
return new FieldDependenciesManager(myFieldDependencies, myFields).getRoots();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JavaElementArrangementEntry> getFields() {
|
||||
return myFields.values();
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
|
||||
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
|
||||
@@ -34,8 +35,6 @@ import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.std.ArrangementColorsAware;
|
||||
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsAware;
|
||||
import com.intellij.psi.codeStyle.arrangement.std.*;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,10 +45,10 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.*;
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.General.*;
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Grouping.*;
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*;
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.*;
|
||||
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.General.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -250,19 +249,34 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
setupOverriddenMethods(parseInfo);
|
||||
}
|
||||
}
|
||||
setupFieldInitializationDependencies(parseInfo.getFieldDependencyRoots());
|
||||
List<ArrangementEntryDependencyInfo> fieldDependencyRoots = parseInfo.getFieldDependencyRoots();
|
||||
if (!fieldDependencyRoots.isEmpty()) {
|
||||
setupFieldInitializationDependencies(fieldDependencyRoots, settings, parseInfo);
|
||||
}
|
||||
return parseInfo.getEntries();
|
||||
}
|
||||
|
||||
public void setupFieldInitializationDependencies(@NotNull List<ArrangementEntryDependencyInfo> fieldDependencyRoots) {
|
||||
public void setupFieldInitializationDependencies(@NotNull List<ArrangementEntryDependencyInfo> fieldDependencyRoots,
|
||||
@NotNull ArrangementSettings settings,
|
||||
@NotNull JavaArrangementParseInfo parseInfo)
|
||||
{
|
||||
Collection<JavaElementArrangementEntry> fields = parseInfo.getFields();
|
||||
List<JavaElementArrangementEntry> arrangedFields = ArrangementEngine.arrange(fields, settings.getSections(), settings.getRulesSortedByPriority(), null);
|
||||
|
||||
for (ArrangementEntryDependencyInfo root : fieldDependencyRoots) {
|
||||
JavaElementArrangementEntry anchorField = root.getAnchorEntry();
|
||||
final int anchorEntryIndex = arrangedFields.indexOf(anchorField);
|
||||
|
||||
for (ArrangementEntryDependencyInfo fieldInInitializerInfo : root.getDependentEntriesInfos()) {
|
||||
anchorField.addDependency(fieldInInitializerInfo.getAnchorEntry());
|
||||
JavaElementArrangementEntry fieldInInitializer = fieldInInitializerInfo.getAnchorEntry();
|
||||
if (arrangedFields.indexOf(fieldInInitializer) > anchorEntryIndex) {
|
||||
anchorField.addDependency(fieldInInitializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBlankLines(@NotNull CodeStyleSettings settings,
|
||||
@Nullable JavaElementArrangementEntry parent,
|
||||
|
||||
@@ -17,8 +17,10 @@ package com.intellij.spellchecker;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import com.intellij.psi.PsiLiteralExpression;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.spellchecker.inspections.PlainTextSplitter;
|
||||
@@ -30,8 +32,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
*
|
||||
* @author shkate@jetbrains.com
|
||||
*/
|
||||
public class LiteralExpressionTokenizer extends Tokenizer<PsiLiteralExpression> {
|
||||
@@ -42,6 +42,8 @@ public class LiteralExpressionTokenizer extends Tokenizer<PsiLiteralExpression>
|
||||
return; // not a string literal
|
||||
}
|
||||
|
||||
if (InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) return;
|
||||
|
||||
final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class);
|
||||
if (listOwner != null && AnnotationUtil.isAnnotated(listOwner, Collections.singleton(AnnotationUtil.NON_NLS), false, false)) {
|
||||
return;
|
||||
|
||||
+17
-2
@@ -48,6 +48,7 @@ import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -703,7 +704,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
else if (element instanceof PsiComment) {
|
||||
return settings.isCollapseEndOfLineComments();
|
||||
}
|
||||
else if (element instanceof PsiLiteralExpression
|
||||
else if (isLiteralExpression(element)
|
||||
&& element.getParent() instanceof PsiExpressionList
|
||||
&& (element.getParent().getParent() instanceof PsiCallExpression
|
||||
|| element.getParent().getParent() instanceof PsiAnonymousClass)) {
|
||||
@@ -775,7 +776,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
for (int i = 0; i < callArguments.length; i++) {
|
||||
PsiExpression callArgument = callArguments[i];
|
||||
|
||||
if (callArgument instanceof PsiLiteralExpression) {
|
||||
if (isLiteralExpression(callArgument)) {
|
||||
if (!isResolved) {
|
||||
PsiMethod method = expression.resolveMethod();
|
||||
isResolved = true;
|
||||
@@ -799,6 +800,20 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
private static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
|
||||
if (callArgument instanceof PsiLiteralExpression)
|
||||
return true;
|
||||
|
||||
if (callArgument instanceof PsiPrefixExpression) {
|
||||
PsiPrefixExpression expr = (PsiPrefixExpression)callArgument;
|
||||
IElementType tokenType = expr.getOperationTokenType();
|
||||
return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
|
||||
@NotNull Set<PsiElement> processedComments, final boolean quick) {
|
||||
if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class Test {
|
||||
void foo(final Stream<Person> stream) {
|
||||
final Map<String,List<Person>> mapByFirstLetter = stream.collect(Collectors.groupingBy(p -> "" + p.name.charAt(0)));
|
||||
|
||||
final String vV = mapByFirstLetter.values().stream().map(lp -> lp.stream().map(p -> p.name)
|
||||
.collect(Collectors.joining("/","<",">"))) .collect(Collectors.joining(" : "));
|
||||
|
||||
final String vV2 = mapByFirstLetter.values().stream()
|
||||
.map(lp -> lp.stream().map(Person::getName).collect(Collectors.joining("/","<",">")))
|
||||
.collect(Collectors.joining(" : "));
|
||||
System.out.println("mapByFirstLetter2 : "+ vV2);
|
||||
}
|
||||
|
||||
public static class Person {
|
||||
private String name;
|
||||
public Person(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName() {return name;}
|
||||
}
|
||||
}
|
||||
+4
@@ -234,6 +234,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA126109() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
@@ -698,6 +698,29 @@ public class CharSymbol {
|
||||
assert regions[2].placeholderText == "fast: false"
|
||||
}
|
||||
|
||||
public void "test inline negative numbers (IDEA-126753)"() {
|
||||
def text = """
|
||||
public class CharSymbol {
|
||||
|
||||
public void main() {
|
||||
Object obj = new Object();
|
||||
count(-1, obj);
|
||||
}
|
||||
|
||||
public void count(int test, Object obj) {
|
||||
Object tmp = obj;
|
||||
boolean isFast = false;
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 3
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "-1")
|
||||
assert regions[1].placeholderText == "test: -1"
|
||||
}
|
||||
|
||||
public void "test inline constructor literal arguments names"() {
|
||||
def text = """
|
||||
public class Test {
|
||||
|
||||
+54
-2
@@ -328,9 +328,61 @@ class Second extends First {
|
||||
)
|
||||
}
|
||||
|
||||
void "test IDEA-123875"() {
|
||||
doTest(
|
||||
initial: '''\
|
||||
public class RearrangeFail {
|
||||
|
||||
public static final byte[] ENTITIES_END = "</entities>".getBytes();
|
||||
private final Element entitiesEndElement = new Element(ENTITIES_END);
|
||||
|
||||
|
||||
|
||||
public static final byte[] ENTITIES_START = "<entities>".getBytes();
|
||||
private final Element entitiesStartElement = new Element(ENTITIES_START);
|
||||
|
||||
}
|
||||
''',
|
||||
expected: '''\
|
||||
public class RearrangeFail {
|
||||
|
||||
public static final byte[] ENTITIES_END = "</entities>".getBytes();
|
||||
public static final byte[] ENTITIES_START = "<entities>".getBytes();
|
||||
private final Element entitiesEndElement = new Element(ENTITIES_END);
|
||||
private final Element entitiesStartElement = new Element(ENTITIES_START);
|
||||
|
||||
}
|
||||
''',
|
||||
rules: [
|
||||
rule(PUBLIC, STATIC, FINAL),
|
||||
rule(PRIVATE),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
void "test IDEA-125099"() {
|
||||
doTest(
|
||||
initial: '''\
|
||||
public class test {
|
||||
|
||||
private int a = 2;
|
||||
|
||||
public static final String TEST = "1";
|
||||
public static final String SHOULD_BE_IN_BETWEEN = "2";
|
||||
public static final String USERS_ROLE_ID_COLUMN = TEST;
|
||||
}
|
||||
''',
|
||||
expected: '''\
|
||||
public class test {
|
||||
|
||||
public static final String TEST = "1";
|
||||
public static final String SHOULD_BE_IN_BETWEEN = "2";
|
||||
public static final String USERS_ROLE_ID_COLUMN = TEST;
|
||||
private int a = 2;
|
||||
}
|
||||
''',
|
||||
rules: [
|
||||
rule(PUBLIC, STATIC, FINAL),
|
||||
rule(PRIVATE)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
public class SimpleModificationTracker implements ModificationTracker {
|
||||
static {
|
||||
// field made public to workaround bug in JDK7 when AtomicIntegerFieldUpdater can't be created for private field, even from within its own class
|
||||
assert Patches.HACK_USED_WHICH_IS_FIXED_IN_JDK8;
|
||||
// fixed in JDK8
|
||||
assert Patches.JDK_BUG_ID_7103570;
|
||||
}
|
||||
public volatile int myCounter;
|
||||
|
||||
|
||||
+1
@@ -60,6 +60,7 @@ public class VFileContentChangeEvent extends VFileEvent {
|
||||
return "VfsEvent[update: " + myFile.getUrl() + "]";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myFile.getPath();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,7 @@ public class VFileCopyEvent extends VFileEvent {
|
||||
private final VirtualFile myNewParent;
|
||||
private final String myNewChildName;
|
||||
|
||||
public VFileCopyEvent(final Object requestor, final VirtualFile file, final VirtualFile newParent, final String newChildName) {
|
||||
public VFileCopyEvent(final Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent, @NotNull String newChildName) {
|
||||
super(requestor, false);
|
||||
myFile = file;
|
||||
myNewParent = newParent;
|
||||
@@ -37,23 +37,28 @@ public class VFileCopyEvent extends VFileEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getNewParent() {
|
||||
return myNewParent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getNewChildName() {
|
||||
return myNewChildName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "VfsEvent[copy " + myFile +" to " + myNewParent + " as " + myNewChildName +"]";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myNewParent.getPath() + "/" + myNewChildName;
|
||||
@@ -70,6 +75,7 @@ public class VFileCopyEvent extends VFileEvent {
|
||||
return myFile.isValid() && myNewParent.findChild(myNewChildName) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -83,9 +89,9 @@ public class VFileCopyEvent extends VFileEvent {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = myFile.hashCode();
|
||||
int result = myFile.hashCode();
|
||||
result = 31 * result + myNewParent.hashCode();
|
||||
result = 31 * result + myNewChildName.hashCode();
|
||||
return result;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,9 +24,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author max
|
||||
*/
|
||||
public class VFileCreateEvent extends VFileEvent {
|
||||
private final VirtualFile myParent;
|
||||
@NotNull private final VirtualFile myParent;
|
||||
private final boolean myDirectory;
|
||||
private final String myChildName;
|
||||
@NotNull private final String myChildName;
|
||||
private final boolean myReCreation;
|
||||
private VirtualFile myCreatedFile;
|
||||
|
||||
@@ -51,6 +51,7 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
myReCreation = isReCreation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getChildName() {
|
||||
return myChildName;
|
||||
}
|
||||
@@ -59,6 +60,7 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
return myDirectory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getParent() {
|
||||
return myParent;
|
||||
}
|
||||
@@ -74,6 +76,7 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
myChildName + " in " + myParent.getUrl() + "]";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myParent.getPath() + "/" + myChildName;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,11 +40,13 @@ public class VFileDeleteEvent extends VFileEvent {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "VfsEvent[deleted: " + myFile.getUrl() + "]";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myFile.getPath();
|
||||
@@ -61,6 +63,7 @@ public class VFileDeleteEvent extends VFileEvent {
|
||||
return myFile.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -70,6 +73,7 @@ public class VFileDeleteEvent extends VFileEvent {
|
||||
return myFile.equals(event.myFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myFile.hashCode();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,7 @@ public abstract class VFileEvent {
|
||||
return myRequestor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract String getPath();
|
||||
|
||||
/**
|
||||
@@ -58,6 +59,8 @@ public abstract class VFileEvent {
|
||||
|
||||
public abstract boolean isValid();
|
||||
|
||||
@Override
|
||||
public abstract int hashCode();
|
||||
@Override
|
||||
public abstract boolean equals(Object o);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ public class VFileMoveEvent extends VFileEvent {
|
||||
private final VirtualFile myOldParent;
|
||||
private final VirtualFile myNewParent;
|
||||
|
||||
public VFileMoveEvent(final Object requestor, @NotNull final VirtualFile file, final VirtualFile newParent) {
|
||||
public VFileMoveEvent(final Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent) {
|
||||
super(requestor, false);
|
||||
myFile = file;
|
||||
myNewParent = newParent;
|
||||
@@ -43,6 +43,7 @@ public class VFileMoveEvent extends VFileEvent {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getNewParent() {
|
||||
return myNewParent;
|
||||
}
|
||||
@@ -51,11 +52,13 @@ public class VFileMoveEvent extends VFileEvent {
|
||||
return myOldParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "VfsEvent[move " + myFile.getName() +" from " + myOldParent + " to " + myNewParent + "]";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myFile.getPath();
|
||||
@@ -72,6 +75,7 @@ public class VFileMoveEvent extends VFileEvent {
|
||||
return myFile.isValid() && Comparing.equal(myFile.getParent(), myOldParent) && myOldParent.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -85,9 +89,9 @@ public class VFileMoveEvent extends VFileEvent {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = myFile.hashCode();
|
||||
int result = myFile.hashCode();
|
||||
result = 31 * result + myOldParent.hashCode();
|
||||
result = 31 * result + myNewParent.hashCode();
|
||||
return result;
|
||||
|
||||
+2
@@ -91,6 +91,7 @@ public class VFilePropertyChangeEvent extends VFileEvent {
|
||||
return myPropertyName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPath() {
|
||||
return myFile.getPath();
|
||||
@@ -131,6 +132,7 @@ public class VFilePropertyChangeEvent extends VFileEvent {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String toString() {
|
||||
|
||||
@@ -114,6 +114,9 @@ public class PsiFileFactoryImpl extends PsiFileFactory {
|
||||
final PsiFile psiFile = viewProvider.getPsi(language);
|
||||
if (psiFile != null) {
|
||||
if (markAsCopy) {
|
||||
if (psiFile.getNode() == null) {
|
||||
throw new AssertionError("No node for file " + psiFile + "; language=" + language);
|
||||
}
|
||||
markGenerated(psiFile);
|
||||
}
|
||||
return psiFile;
|
||||
|
||||
+9
-3
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -40,13 +41,15 @@ public class CompletionInitializationContext {
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
private final CompletionType myCompletionType;
|
||||
private final int myInvocationCount;
|
||||
private final OffsetMap myOffsetMap;
|
||||
private String myDummyIdentifier = DUMMY_IDENTIFIER;
|
||||
|
||||
public CompletionInitializationContext(final Editor editor, final PsiFile file, final CompletionType completionType) {
|
||||
public CompletionInitializationContext(final Editor editor, final PsiFile file, final CompletionType completionType, int invocationCount) {
|
||||
myEditor = editor;
|
||||
myFile = file;
|
||||
myCompletionType = completionType;
|
||||
myInvocationCount = invocationCount;
|
||||
myOffsetMap = new OffsetMap(editor.getDocument());
|
||||
|
||||
myOffsetMap.addOffset(START_OFFSET, calcStartOffset(editor));
|
||||
@@ -79,7 +82,7 @@ public class CompletionInitializationContext {
|
||||
|
||||
@NotNull
|
||||
public Language getPositionLanguage() {
|
||||
return PsiUtilBase.getLanguageInEditor(getEditor(), getProject());
|
||||
return ObjectUtils.assertNotNull(PsiUtilBase.getLanguageInEditor(getEditor(), getProject()));
|
||||
}
|
||||
|
||||
public String getDummyIdentifier() {
|
||||
@@ -127,9 +130,12 @@ public class CompletionInitializationContext {
|
||||
return getIdentifierEndOffset();
|
||||
}
|
||||
|
||||
public int getInvocationCount() {
|
||||
return myInvocationCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the offset up to which the text will be deleted if a completion variant is selected using Replace character (Tab)
|
||||
* @param idEnd
|
||||
*/
|
||||
public void setReplacementOffset(int idEnd) {
|
||||
myOffsetMap.addOffset(IDENTIFIER_END_OFFSET, idEnd);
|
||||
|
||||
+13
-15
@@ -43,30 +43,30 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
|
||||
@NonNls private static final String OPTION = "option";
|
||||
@NonNls private static final String ENV_VARIABLES = "ENV_VARIABLES";
|
||||
|
||||
private final EnvironmentVariablesTextField myEnvsTextField;
|
||||
private final EnvironmentVariablesTextFieldWithBrowseButton myEnvVars;
|
||||
|
||||
public EnvironmentVariablesComponent() {
|
||||
super();
|
||||
myEnvsTextField = new EnvironmentVariablesTextField();
|
||||
setComponent(myEnvsTextField.getComponent());
|
||||
myEnvVars = new EnvironmentVariablesTextFieldWithBrowseButton();
|
||||
setComponent(myEnvVars);
|
||||
setText(ExecutionBundle.message("environment.variables.component.title"));
|
||||
}
|
||||
|
||||
public void setEnvs(@NotNull Map<String, String> envs) {
|
||||
myEnvsTextField.setEnvs(envs);
|
||||
myEnvVars.setEnvs(envs);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<String, String> getEnvs() {
|
||||
return myEnvsTextField.getEnvs();
|
||||
return myEnvVars.getEnvs();
|
||||
}
|
||||
|
||||
public boolean isPassParentEnvs() {
|
||||
return myEnvsTextField.isPassParentEnvs();
|
||||
return myEnvVars.isPassParentEnvs();
|
||||
}
|
||||
|
||||
public void setPassParentEnvs(final boolean passParentEnvs) {
|
||||
myEnvsTextField.setPassParentEnvs(passParentEnvs);
|
||||
myEnvVars.setPassParentEnvs(passParentEnvs);
|
||||
}
|
||||
|
||||
public static void readExternal(Element element, Map<String, String> envs) {
|
||||
@@ -93,12 +93,10 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
|
||||
private static void splitVars(final Map<String, String> envs, final String val) {
|
||||
if (val != null) {
|
||||
final String[] envVars = val.split(";");
|
||||
if (envVars != null) {
|
||||
for (String envVar : envVars) {
|
||||
final int idx = envVar.indexOf('=');
|
||||
if (idx > -1) {
|
||||
envs.put(envVar.substring(0, idx), idx < envVar.length() - 1 ? envVar.substring(idx + 1) : "");
|
||||
}
|
||||
for (String envVar : envVars) {
|
||||
final int idx = envVar.indexOf('=');
|
||||
if (idx > -1) {
|
||||
envs.put(envVar.substring(0, idx), idx < envVar.length() - 1 ? envVar.substring(idx + 1) : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,11 +132,11 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
|
||||
|
||||
@Override
|
||||
public void addChangeListener(final ChangeListener changeListener) {
|
||||
myEnvsTextField.addChangeListener(changeListener);
|
||||
myEnvVars.addChangeListener(changeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(final ChangeListener changeListener) {
|
||||
myEnvsTextField.removeChangeListener(changeListener);
|
||||
myEnvVars.removeChangeListener(changeListener);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-13
@@ -34,17 +34,16 @@ import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class EnvironmentVariablesTextField {
|
||||
public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton {
|
||||
|
||||
private final TextFieldWithBrowseButton myEnvsTextField;
|
||||
private final Map<String, String> myEnvs = new THashMap<String, String>();
|
||||
private boolean myPassParentEnvs;
|
||||
private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
|
||||
public EnvironmentVariablesTextField() {
|
||||
myEnvsTextField = new TextFieldWithBrowseButton();
|
||||
myEnvsTextField.setEditable(false);
|
||||
myEnvsTextField.addActionListener(new ActionListener() {
|
||||
public EnvironmentVariablesTextFieldWithBrowseButton() {
|
||||
super();
|
||||
setEditable(false);
|
||||
addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
new MyEnvironmentVariablesDialog().show();
|
||||
@@ -52,11 +51,6 @@ public class EnvironmentVariablesTextField {
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextFieldWithBrowseButton getComponent() {
|
||||
return myEnvsTextField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<String, String> getEnvs() {
|
||||
return myEnvs;
|
||||
@@ -66,7 +60,7 @@ public class EnvironmentVariablesTextField {
|
||||
myEnvs.clear();
|
||||
myEnvs.putAll(envs);
|
||||
String envsStr = stringifyEnvs(myEnvs);
|
||||
myEnvsTextField.setText(envsStr);
|
||||
setText(envsStr);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -115,7 +109,7 @@ public class EnvironmentVariablesTextField {
|
||||
private final JPanel myWholePanel = new JPanel(new BorderLayout());
|
||||
|
||||
protected MyEnvironmentVariablesDialog() {
|
||||
super(myEnvsTextField, true);
|
||||
super(EnvironmentVariablesTextFieldWithBrowseButton.this, true);
|
||||
myEnvVariablesTable = new EnvVariablesTable();
|
||||
List<EnvironmentVariable> envVariables = ContainerUtil.newArrayList();
|
||||
for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -217,6 +218,7 @@ public abstract class FindManager {
|
||||
* @param element the element to find the usages for.
|
||||
*/
|
||||
public abstract void findUsages(@NotNull PsiElement element);
|
||||
public abstract void findUsagesInScope(@NotNull PsiElement element, @NotNull SearchScope searchScope);
|
||||
|
||||
/**
|
||||
* Shows the Find Usages dialog (if {@code showDialog} is true} and performs the Find Usages operation for the
|
||||
|
||||
+14
-13
@@ -135,19 +135,18 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
*/
|
||||
|
||||
int newTime = phase.newCompletionStarted(time, repeated);
|
||||
final int newTime = phase.newCompletionStarted(time, repeated);
|
||||
if (invokedExplicitly) {
|
||||
time = newTime;
|
||||
}
|
||||
final int invocationCount = time;
|
||||
if (CompletionServiceImpl.isPhase(CompletionPhase.InsertedSingleItem.class)) {
|
||||
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
|
||||
}
|
||||
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass(), CompletionPhase.CommittingDocuments.class);
|
||||
|
||||
if (time > 1) {
|
||||
if (myCompletionType == CompletionType.BASIC) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
|
||||
}
|
||||
if (invocationCount > 1 && myCompletionType == CompletionType.BASIC) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
|
||||
}
|
||||
|
||||
final CompletionInitializationContext[] initializationContext = {null};
|
||||
@@ -168,7 +167,7 @@ public class CodeCompletionHandlerBase {
|
||||
psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
|
||||
CompletionAssertions.assertCommitSuccessful(editor, psiFile);
|
||||
|
||||
initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile);
|
||||
initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile, invocationCount);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
@@ -184,12 +183,12 @@ public class CodeCompletionHandlerBase {
|
||||
CommandProcessor.getInstance().executeCommand(project, initCmd, null, null);
|
||||
}
|
||||
|
||||
insertDummyIdentifier(initializationContext[0], hasModifiers, time);
|
||||
insertDummyIdentifier(initializationContext[0], hasModifiers, invocationCount);
|
||||
}
|
||||
|
||||
private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile) {
|
||||
private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile, int invocationCount) {
|
||||
final Ref<CompletionContributor> current = Ref.create(null);
|
||||
CompletionInitializationContext context = new CompletionInitializationContext(editor, psiFile, myCompletionType) {
|
||||
CompletionInitializationContext context = new CompletionInitializationContext(editor, psiFile, myCompletionType, invocationCount) {
|
||||
CompletionContributor dummyIdentifierChanger;
|
||||
|
||||
@Override
|
||||
@@ -759,10 +758,12 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
|
||||
final Language language = PsiUtilBase.getLanguageInEditor(editor, project);
|
||||
final List<SmartEnterProcessor> processors = SmartEnterProcessors.INSTANCE.forKey(language);
|
||||
if (processors.size() > 0) {
|
||||
for (SmartEnterProcessor processor : processors) {
|
||||
processor.process(project, editor, indicator.getParameters().getOriginalFile());
|
||||
if (language != null) {
|
||||
final List<SmartEnterProcessor> processors = SmartEnterProcessors.INSTANCE.forKey(language);
|
||||
if (processors.size() > 0) {
|
||||
for (SmartEnterProcessor processor : processors) {
|
||||
processor.process(project, editor, indicator.getParameters().getOriginalFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
|
||||
import com.intellij.codeInsight.hint.TooltipController;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.ide.todo.TodoConfiguration;
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -599,6 +600,7 @@ public class DaemonListeners implements Disposable {
|
||||
if (editor.offsetToLogicalPosition(offset).column != logical.column) return; // we are in virtual space
|
||||
HighlightInfo info = myDaemonCodeAnalyzer.findHighlightByOffset(editor.getDocument(), offset, false);
|
||||
if (info == null || info.getDescription() == null) return;
|
||||
if (IdeTooltipManager.getInstance().hasCurrent()) return;
|
||||
DaemonTooltipUtil.showInfoTooltip(info, editor, offset);
|
||||
shown = true;
|
||||
}
|
||||
|
||||
@@ -51,10 +51,7 @@ public class LookupOffsets {
|
||||
private void updateLookupStart(int minPrefixLength) {
|
||||
int offset = getPivotOffset();
|
||||
int start = offset - minPrefixLength - myAdditionalPrefix.length() + myRemovedPrefix;
|
||||
if (start < 0) {
|
||||
LOG.error("Invalid start offset: o=" + offset + ", mpl=" + minPrefixLength + ", ap=" + myAdditionalPrefix + ", rp=" + myRemovedPrefix);
|
||||
return;
|
||||
}
|
||||
start = Math.max(Math.min(start, myEditor.getDocument().getTextLength()), 0);
|
||||
if (myLookupStartMarker != null) {
|
||||
if (myLookupStartMarker.isValid() && myLookupStartMarker.getStartOffset() == start && myLookupStartMarker.getEndOffset() == start) {
|
||||
return;
|
||||
|
||||
@@ -162,16 +162,9 @@ public class ConsoleExecuteAction extends DumbAwareAction {
|
||||
protected void beforeExecution(@NotNull LanguageConsoleImpl console) {
|
||||
}
|
||||
|
||||
protected boolean shouldExecute(@NotNull LanguageConsoleImpl console) {
|
||||
protected void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) {
|
||||
//noinspection deprecation
|
||||
beforeExecution(console);
|
||||
return true;
|
||||
}
|
||||
|
||||
final void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) {
|
||||
if (!shouldExecute(console)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String text = console.prepareExecuteAction(myAddToHistory, myPreserveMarkup, true);
|
||||
((UndoManagerImpl)UndoManager.getInstance(console.getProject())).invalidateActionsFor(DocumentReferenceManager.getInstance().create(console.getCurrentEditor().getDocument()));
|
||||
|
||||
+9
-11
@@ -22,6 +22,7 @@ import com.intellij.facet.FacetManagerAdapter;
|
||||
import com.intellij.facet.FacetModificationTrackingService;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.util.ModificationTrackerListener;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SimpleModificationTracker;
|
||||
@@ -35,8 +36,8 @@ import java.util.Map;
|
||||
* @author nik
|
||||
*/
|
||||
public class FacetModificationTrackingServiceImpl extends FacetModificationTrackingService {
|
||||
private final Map<Facet, Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>>> myModificationsTrackers =
|
||||
new THashMap<Facet, Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>>>();
|
||||
private final Map<Facet, Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>>> myModificationsTrackers =
|
||||
new THashMap<Facet, Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>>>();
|
||||
|
||||
public FacetModificationTrackingServiceImpl(final Module module) {
|
||||
module.getMessageBus().connect().subscribe(FacetManager.FACETS_TOPIC, new FacetModificationTrackingListener());
|
||||
@@ -44,14 +45,14 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FacetModificationTracker getFacetModificationTracker(@NotNull final Facet facet) {
|
||||
public ModificationTracker getFacetModificationTracker(@NotNull final Facet facet) {
|
||||
return getFacetInfo(facet).first;
|
||||
}
|
||||
|
||||
private Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> getFacetInfo(final Facet facet) {
|
||||
Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
|
||||
private Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> getFacetInfo(final Facet facet) {
|
||||
Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
|
||||
if (pair == null) {
|
||||
pair = Pair.create(new FacetModificationTracker(), EventDispatcher.create(ModificationTrackerListener.class));
|
||||
pair = Pair.create(new SimpleModificationTracker(), EventDispatcher.create(ModificationTrackerListener.class));
|
||||
myModificationsTrackers.put(facet, pair);
|
||||
}
|
||||
return pair;
|
||||
@@ -59,7 +60,7 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
|
||||
|
||||
@Override
|
||||
public void incFacetModificationTracker(@NotNull final Facet facet) {
|
||||
final Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = getFacetInfo(facet);
|
||||
final Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = getFacetInfo(facet);
|
||||
pair.first.incModificationCount();
|
||||
pair.second.getMulticaster().modificationCountChanged(facet);
|
||||
}
|
||||
@@ -74,13 +75,10 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
|
||||
getFacetInfo(facet).second.removeListener(listener);
|
||||
}
|
||||
|
||||
private static class FacetModificationTracker extends SimpleModificationTracker {
|
||||
}
|
||||
|
||||
private class FacetModificationTrackingListener extends FacetManagerAdapter {
|
||||
@Override
|
||||
public void facetConfigurationChanged(@NotNull final Facet facet) {
|
||||
final Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
|
||||
final Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
|
||||
if (pair != null) {
|
||||
pair.first.incModificationCount();
|
||||
pair.second.getMulticaster().modificationCountChanged(facet);
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
@@ -50,7 +51,6 @@ import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.ui.*;
|
||||
@@ -84,14 +84,17 @@ import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
private final boolean showSettingsDialogBefore;
|
||||
private static final int USAGES_PAGE_SIZE = 100;
|
||||
|
||||
static final NullUsage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE;
|
||||
static final Usage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE;
|
||||
private static final UsageNode MORE_USAGES_SEPARATOR_NODE = UsageViewImpl.NULL_NODE;
|
||||
static final Usage USAGES_OUTSIDE_SCOPE_SEPARATOR = new UsageAdapter();
|
||||
private static final UsageNode USAGES_OUTSIDE_SCOPE_NODE = new UsageNode(USAGES_OUTSIDE_SCOPE_SEPARATOR, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
|
||||
|
||||
private static final Comparator<UsageNode> USAGE_NODE_COMPARATOR = new Comparator<UsageNode>() {
|
||||
@Override
|
||||
@@ -100,8 +103,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
if (c2 instanceof StringNode) return -1;
|
||||
Usage o1 = c1.getUsage();
|
||||
Usage o2 = c2.getUsage();
|
||||
if (o1 == MORE_USAGES_SEPARATOR) return 1;
|
||||
if (o2 == MORE_USAGES_SEPARATOR) return -1;
|
||||
int weight1 = o1 == USAGES_OUTSIDE_SCOPE_SEPARATOR ? 2 : o1 == MORE_USAGES_SEPARATOR ? 1 : 0;
|
||||
int weight2 = o2 == USAGES_OUTSIDE_SCOPE_SEPARATOR ? 2 : o2 == MORE_USAGES_SEPARATOR ? 1 : 0;
|
||||
if (weight1 != weight2) return weight1 - weight2;
|
||||
|
||||
VirtualFile v1 = UsageListCellRenderer.getVirtualFile(o1);
|
||||
VirtualFile v2 = UsageListCellRenderer.getVirtualFile(o2);
|
||||
@@ -193,26 +197,18 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
private void startFindUsages(@NotNull PsiElement element, @NotNull RelativePoint popupPosition, Editor editor, int maxUsages) {
|
||||
Project project = element.getProject();
|
||||
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
|
||||
FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false);
|
||||
FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false);
|
||||
if (handler == null) return;
|
||||
if (showSettingsDialogBefore) {
|
||||
showDialogAndFindUsages(handler, popupPosition, editor, maxUsages);
|
||||
return;
|
||||
}
|
||||
showElementUsages(handler, editor, popupPosition, maxUsages, getDefaultOptions(handler));
|
||||
showElementUsages(editor, popupPosition, handler, maxUsages, handler.getFindUsagesOptions(DataManager.getInstance().getDataContext()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FindUsagesOptions getDefaultOptions(@NotNull FindUsagesHandler handler) {
|
||||
FindUsagesOptions options = handler.getFindUsagesOptions(DataManager.getInstance().getDataContext());
|
||||
// by default, scope in FindUsagesOptions is copied from the FindSettings, but we need a default one
|
||||
options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
|
||||
return options;
|
||||
}
|
||||
|
||||
private void showElementUsages(@NotNull final FindUsagesHandler handler,
|
||||
final Editor editor,
|
||||
private void showElementUsages(final Editor editor,
|
||||
@NotNull final RelativePoint popupPosition,
|
||||
@NotNull final FindUsagesHandler handler,
|
||||
final int maxUsages,
|
||||
@NotNull final FindUsagesOptions options) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
@@ -236,30 +232,26 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
usageViewSettings.loadState(savedGlobalSettings);
|
||||
}
|
||||
});
|
||||
final AtomicInteger outOfScopeUsages = new AtomicInteger();
|
||||
|
||||
final List<Usage> usages = new ArrayList<Usage>();
|
||||
final Set<UsageNode> visibleNodes = new LinkedHashSet<UsageNode>();
|
||||
|
||||
final MyTable table = new MyTable();
|
||||
final AsyncProcessIcon processIcon = new AsyncProcessIcon("xxx");
|
||||
boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE);
|
||||
if (hadMoreSeparator) {
|
||||
usages.add(MORE_USAGES_SEPARATOR);
|
||||
visibleNodes.add(MORE_USAGES_SEPARATOR_NODE);
|
||||
}
|
||||
|
||||
addUsageNodes(usageView.getRoot(), usageView, new ArrayList<UsageNode>());
|
||||
|
||||
TableScrollingUtil.installActions(table);
|
||||
|
||||
final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
|
||||
setTableModel(table, usageView, data);
|
||||
setTableModel(table, usageView, data, outOfScopeUsages, options.searchScope);
|
||||
|
||||
SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
|
||||
speedSearch.setComparator(new SpeedSearchComparator(false));
|
||||
|
||||
final JBPopup popup = createUsagePopup(usages, visibleNodes, handler, editor, popupPosition,
|
||||
maxUsages, usageView, options, table, presentation, processIcon, hadMoreSeparator);
|
||||
maxUsages, usageView, options, table, presentation, processIcon);
|
||||
|
||||
Disposer.register(popup, usageView);
|
||||
|
||||
@@ -293,7 +285,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
copy = new ArrayList<Usage>(usages);
|
||||
}
|
||||
|
||||
rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed());
|
||||
rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed(), outOfScopeUsages,
|
||||
options.searchScope);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -305,11 +298,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())};
|
||||
Processor<Usage> collect = new Processor<Usage>() {
|
||||
private final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())};
|
||||
@Override
|
||||
public boolean process(@NotNull final Usage usage) {
|
||||
if (!UsageViewManagerImpl.isInScope(usage, options.searchScope)) {
|
||||
if (outOfScopeUsages.getAndIncrement() == 0) {
|
||||
visibleNodes.add(USAGES_OUTSIDE_SCOPE_NODE);
|
||||
usages.add(USAGES_OUTSIDE_SCOPE_SEPARATOR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
synchronized (usages) {
|
||||
if (visibleNodes.size() >= maxUsages) return false;
|
||||
if(UsageViewManager.isSelfUsage(usage, myUsageTarget)) return true;
|
||||
@@ -352,8 +351,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
synchronized (usages) {
|
||||
if (visibleNodes.isEmpty()) {
|
||||
if (usages.isEmpty()) {
|
||||
String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options, project));
|
||||
showHint(text, editor, popupPosition, handler, maxUsages, options);
|
||||
String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options));
|
||||
hint(editor, text, handler, popupPosition, maxUsages, options, false);
|
||||
popup.cancel();
|
||||
}
|
||||
else {
|
||||
@@ -364,8 +363,13 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
if (usages.size() == 1) {
|
||||
//the only usage
|
||||
Usage usage = visibleNodes.iterator().next().getUsage();
|
||||
String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options, project));
|
||||
navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
|
||||
if (usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) {
|
||||
hint(editor, UsageViewManagerImpl.outOfScopeMessage(outOfScopeUsages.get(), options.searchScope), handler, popupPosition, maxUsages, options, true);
|
||||
}
|
||||
else {
|
||||
String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options));
|
||||
navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
|
||||
}
|
||||
popup.cancel();
|
||||
}
|
||||
else {
|
||||
@@ -373,7 +377,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
// usage view can filter usages down to one
|
||||
Usage visibleUsage = visibleNodes.iterator().next().getUsage();
|
||||
if (areAllUsagesInOneLine(visibleUsage, usages)) {
|
||||
String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options, project));
|
||||
String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options));
|
||||
navigateAndHint(visibleUsage, hint, handler, popupPosition, maxUsages, options);
|
||||
popup.cancel();
|
||||
}
|
||||
@@ -451,21 +455,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void showHint(@NotNull String text,
|
||||
@Nullable final Editor editor,
|
||||
@NotNull final RelativePoint popupPosition,
|
||||
@NotNull FindUsagesHandler handler,
|
||||
int maxUsages,
|
||||
@NotNull FindUsagesOptions options) {
|
||||
JComponent label = createHintComponent(text, handler, popupPosition, editor, HIDE_HINTS_ACTION, maxUsages, options);
|
||||
if (editor == null || editor.isDisposed() || !editor.getComponent().isShowing()) {
|
||||
HintManager.getInstance().showHint(label, popupPosition, HintManager.HIDE_BY_ANY_KEY |
|
||||
HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0);
|
||||
}
|
||||
else {
|
||||
HintManager.getInstance().showInformationHint(editor, label);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JComponent createHintComponent(@NotNull String text,
|
||||
@@ -474,8 +463,12 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
final Editor editor,
|
||||
@NotNull final Runnable cancelAction,
|
||||
final int maxUsages,
|
||||
@NotNull final FindUsagesOptions options) {
|
||||
@NotNull final FindUsagesOptions options,
|
||||
boolean isWarning) {
|
||||
JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text + " "));
|
||||
if (isWarning) {
|
||||
label.setBackground(MessageType.WARNING.getPopupBackground());
|
||||
}
|
||||
InplaceButton button = createSettingsButton(handler, popupPosition, editor, maxUsages, cancelAction);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout()) {
|
||||
@@ -540,19 +533,13 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
if (dialog.isOK()) {
|
||||
dialog.calcFindUsagesOptions();
|
||||
FindUsagesOptions options = handler.getFindUsagesOptions(DataManager.getInstance().getDataContext());
|
||||
showElementUsages(handler, editor, popupPosition, maxUsages, options);
|
||||
showElementUsages(editor, popupPosition, handler, maxUsages, options);
|
||||
}
|
||||
}
|
||||
|
||||
private static String searchScopePresentableName(@NotNull FindUsagesOptions options, @NotNull Project project) {
|
||||
return notNullizeScope(options, project).getDisplayName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SearchScope notNullizeScope(@NotNull FindUsagesOptions options, @NotNull Project project) {
|
||||
SearchScope scope = options.searchScope;
|
||||
if (scope == null) return ProjectScope.getAllScope(project);
|
||||
return scope;
|
||||
private static String searchScopePresentableName(@NotNull FindUsagesOptions options) {
|
||||
return options.searchScope.getDisplayName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -566,8 +553,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
@NotNull final FindUsagesOptions options,
|
||||
@NotNull final JTable table,
|
||||
@NotNull final UsageViewPresentation presentation,
|
||||
@NotNull final AsyncProcessIcon processIcon,
|
||||
boolean hadMoreSeparator) {
|
||||
@NotNull final AsyncProcessIcon processIcon) {
|
||||
table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2);
|
||||
table.setShowGrid(false);
|
||||
table.setShowVerticalLines(false);
|
||||
@@ -579,14 +565,15 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
PopupChooserBuilder builder = new PopupChooserBuilder(table);
|
||||
final String title = presentation.getTabText();
|
||||
if (title != null) {
|
||||
String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true);
|
||||
String result = getFullTitle(usages, title, false, visibleNodes.size() - 1, true);
|
||||
builder.setTitle(result);
|
||||
builder.setAdText(getSecondInvocationTitle(options, handler));
|
||||
}
|
||||
|
||||
builder.setMovable(true).setResizable(true);
|
||||
final AtomicReference<Object> selectedUsage = new AtomicReference<Object>();
|
||||
final AtomicBoolean moreUsages = new AtomicBoolean();
|
||||
final AtomicBoolean moreUsagesSelected = new AtomicBoolean();
|
||||
final AtomicBoolean outsideScopeUsagesSelected = new AtomicBoolean();
|
||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
@@ -596,12 +583,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
Object value = table.getValueAt(i, 0);
|
||||
if (value instanceof UsageNode) {
|
||||
Usage usage = ((UsageNode)value).getUsage();
|
||||
if (usage == MORE_USAGES_SEPARATOR) {
|
||||
moreUsages.set(true);
|
||||
outsideScopeUsagesSelected.set(false);
|
||||
moreUsagesSelected.set(false);
|
||||
if (usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) {
|
||||
outsideScopeUsagesSelected.set(true);
|
||||
selectedUsage.set(null);
|
||||
}
|
||||
else if (usage == MORE_USAGES_SEPARATOR) {
|
||||
moreUsagesSelected.set(true);
|
||||
selectedUsage.set(null);
|
||||
}
|
||||
else {
|
||||
moreUsages.set(false);
|
||||
selectedUsage.set(usage instanceof UsageInfo2UsageAdapter ? ((UsageInfo2UsageAdapter)usage).getUsageInfo().copy() : usage);
|
||||
}
|
||||
break;
|
||||
@@ -613,10 +605,15 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
builder.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (moreUsages.get()) {
|
||||
if (moreUsagesSelected.get()) {
|
||||
appendMoreUsages(editor, popupPosition, handler, maxUsages, options);
|
||||
return;
|
||||
}
|
||||
if (outsideScopeUsagesSelected.get()) {
|
||||
options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
|
||||
showElementUsages(editor, popupPosition, handler, maxUsages, options);
|
||||
return;
|
||||
}
|
||||
Object usage = selectedUsage.get();
|
||||
if (usage instanceof UsageInfo) {
|
||||
UsageViewUtil.navigateTo((UsageInfo)usage, true);
|
||||
@@ -684,7 +681,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
JComponent content = popup[0].getContent();
|
||||
|
||||
myWidth = (int)(toolBar.getPreferredSize().getWidth()
|
||||
+ new JLabel(getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true)).getPreferredSize().getWidth()
|
||||
+ new JLabel(getFullTitle(usages, title, false, visibleNodes.size() - 1, true)).getPreferredSize().getWidth()
|
||||
+ settingsButton.getPreferredSize().getWidth());
|
||||
myWidth = -1;
|
||||
for (AnAction action : toolbar.getChildren(null)) {
|
||||
@@ -770,7 +767,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
private static String getSecondInvocationTitle(@NotNull FindUsagesOptions options, @NotNull FindUsagesHandler handler) {
|
||||
if (getShowUsagesShortcut() != null) {
|
||||
GlobalSearchScope maximalScope = FindUsagesManager.getMaximalScope(handler);
|
||||
if (!notNullizeScope(options, handler.getProject()).equals(maximalScope)) {
|
||||
if (!options.searchScope.equals(maximalScope)) {
|
||||
return "Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) + " again to search in " + maximalScope.getDisplayName();
|
||||
}
|
||||
}
|
||||
@@ -784,7 +781,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
int maxUsages) {
|
||||
FindUsagesOptions cloned = options.clone();
|
||||
cloned.searchScope = FindUsagesManager.getMaximalScope(handler);
|
||||
showElementUsages(handler, editor, popupPosition, maxUsages, cloned);
|
||||
showElementUsages(editor, popupPosition, handler, maxUsages, cloned);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -827,7 +824,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
@NotNull
|
||||
private static MyModel setTableModel(@NotNull JTable table,
|
||||
@NotNull UsageViewImpl usageView,
|
||||
@NotNull final List<UsageNode> data) {
|
||||
@NotNull final List<UsageNode> data,
|
||||
@NotNull AtomicInteger outOfScopeUsages,
|
||||
@NotNull SearchScope searchScope) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final int columnCount = calcColumnCount(data);
|
||||
MyModel model = table.getModel() instanceof MyModel ? (MyModel)table.getModel() : null;
|
||||
@@ -835,7 +834,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
model = new MyModel(data, columnCount);
|
||||
table.setModel(model);
|
||||
|
||||
ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView);
|
||||
ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView, outOfScopeUsages, searchScope);
|
||||
for (int i=0;i<table.getColumnModel().getColumnCount();i++) {
|
||||
TableColumn column = table.getColumnModel().getColumn(i);
|
||||
column.setCellRenderer(renderer);
|
||||
@@ -908,21 +907,27 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
@NotNull final JBPopup popup,
|
||||
@NotNull final UsageViewPresentation presentation,
|
||||
@NotNull final RelativePoint popupPosition,
|
||||
boolean findUsagesInProgress) {
|
||||
boolean findUsagesInProgress,
|
||||
@NotNull AtomicInteger outOfScopeUsages,
|
||||
@NotNull SearchScope searchScope) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
|
||||
boolean shouldShowMoreSeparator = usages.contains(MORE_USAGES_SEPARATOR);
|
||||
if (shouldShowMoreSeparator) {
|
||||
nodes.add(MORE_USAGES_SEPARATOR_NODE);
|
||||
}
|
||||
boolean hasOutsideScopeUsages = usages.contains(USAGES_OUTSIDE_SCOPE_SEPARATOR);
|
||||
if (hasOutsideScopeUsages && !shouldShowMoreSeparator) {
|
||||
nodes.add(USAGES_OUTSIDE_SCOPE_NODE);
|
||||
}
|
||||
|
||||
String title = presentation.getTabText();
|
||||
String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator, nodes.size() - (shouldShowMoreSeparator ? 1 : 0), findUsagesInProgress);
|
||||
String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator || hasOutsideScopeUsages, nodes.size() - (shouldShowMoreSeparator || hasOutsideScopeUsages ? 1 : 0), findUsagesInProgress);
|
||||
|
||||
((AbstractPopup)popup).setCaption(fullTitle);
|
||||
|
||||
List<UsageNode> data = collectData(usages, nodes, usageView, presentation);
|
||||
MyModel tableModel = setTableModel(table, usageView, data);
|
||||
MyModel tableModel = setTableModel(table, usageView, data, outOfScopeUsages, searchScope);
|
||||
List<UsageNode> existingData = tableModel.getItems();
|
||||
|
||||
int row = table.getSelectedRow();
|
||||
@@ -1021,8 +1026,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
private void appendMoreUsages(Editor editor,
|
||||
@NotNull RelativePoint popupPosition,
|
||||
@NotNull FindUsagesHandler handler,
|
||||
int maxUsages, final FindUsagesOptions options) {
|
||||
showElementUsages(handler, editor, popupPosition, maxUsages+USAGES_PAGE_SIZE, options);
|
||||
int maxUsages,
|
||||
@NotNull FindUsagesOptions options) {
|
||||
showElementUsages(editor, popupPosition, handler, maxUsages+USAGES_PAGE_SIZE, options);
|
||||
}
|
||||
|
||||
private static void addUsageNodes(@NotNull GroupNode root, @NotNull final UsageViewImpl usageView, @NotNull List<UsageNode> outNodes) {
|
||||
@@ -1054,25 +1060,51 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
if (hint == null) return;
|
||||
final Editor newEditor = getEditorFor(usage);
|
||||
if (newEditor == null) return;
|
||||
hint(newEditor, hint, handler, popupPosition, maxUsages, options, false);
|
||||
}
|
||||
|
||||
private void showHint(@Nullable final Editor editor,
|
||||
@NotNull String hint,
|
||||
@NotNull FindUsagesHandler handler,
|
||||
@NotNull final RelativePoint popupPosition,
|
||||
int maxUsages,
|
||||
@NotNull FindUsagesOptions options,
|
||||
boolean isWarning) {
|
||||
JComponent label = createHintComponent(hint, handler, popupPosition, editor, HIDE_HINTS_ACTION, maxUsages, options, isWarning);
|
||||
if (editor == null || editor.isDisposed() || !editor.getComponent().isShowing()) {
|
||||
HintManager.getInstance().showHint(label, popupPosition, HintManager.HIDE_BY_ANY_KEY |
|
||||
HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0);
|
||||
}
|
||||
else {
|
||||
HintManager.getInstance().showInformationHint(editor, label);
|
||||
}
|
||||
}
|
||||
|
||||
private void hint(@Nullable final Editor editor,
|
||||
@NotNull final String hint,
|
||||
@NotNull final FindUsagesHandler handler,
|
||||
@NotNull final RelativePoint popupPosition,
|
||||
final int maxUsages,
|
||||
@NotNull final FindUsagesOptions options,
|
||||
final boolean isWarning) {
|
||||
final Project project = handler.getProject();
|
||||
//opening editor is performing in invokeLater
|
||||
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
newEditor.getScrollingModel().runActionOnScrollingFinished(new Runnable() {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// after new editor created, some editor resizing events are still bubbling. To prevent hiding hint, invokeLater this
|
||||
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (newEditor.getComponent().isShowing()) {
|
||||
showHint(hint, newEditor, popupPosition, handler, maxUsages, options);
|
||||
}
|
||||
showHint(editor, hint, handler, popupPosition, maxUsages, options, isWarning);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
if (editor == null) runnable.run(); else editor.getScrollingModel().runActionOnScrollingFinished(runnable);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1119,9 +1151,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
}
|
||||
|
||||
static class StringNode extends UsageNode {
|
||||
private final Object myString;
|
||||
@NotNull private final Object myString;
|
||||
|
||||
public StringNode(Object string) {
|
||||
public StringNode(@NotNull Object string) {
|
||||
super(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
|
||||
myString = string;
|
||||
}
|
||||
@@ -1159,7 +1191,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
|
||||
UsageNode node = (UsageNode)element;
|
||||
if (node instanceof StringNode) return "";
|
||||
Usage usage = node.getUsage();
|
||||
if (usage == MORE_USAGES_SEPARATOR) return "";
|
||||
if (usage == MORE_USAGES_SEPARATOR || usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) return "";
|
||||
GroupNode group = (GroupNode)node.getParent();
|
||||
return usage.getPresentation().getPlainText() + group;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.ui.FileColorManager;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
@@ -30,24 +31,30 @@ import com.intellij.usages.UsagePresentation;
|
||||
import com.intellij.usages.impl.GroupNode;
|
||||
import com.intellij.usages.impl.UsageNode;
|
||||
import com.intellij.usages.impl.UsageViewImpl;
|
||||
import com.intellij.usages.impl.UsageViewManagerImpl;
|
||||
import com.intellij.usages.rules.UsageInFile;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
class ShowUsagesTableCellRenderer implements TableCellRenderer {
|
||||
private final UsageViewImpl myUsageView;
|
||||
@NotNull private final AtomicInteger myOutOfScopeUsages;
|
||||
@NotNull private final SearchScope mySearchScope;
|
||||
|
||||
ShowUsagesTableCellRenderer(@NotNull UsageViewImpl usageView) {
|
||||
ShowUsagesTableCellRenderer(@NotNull UsageViewImpl usageView, @NotNull AtomicInteger outOfScopeUsages, @NotNull SearchScope searchScope) {
|
||||
myUsageView = usageView;
|
||||
myOutOfScopeUsages = outOfScopeUsages;
|
||||
mySearchScope = searchScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,32 +67,37 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer {
|
||||
Color fileBgColor = getBackgroundColor(isSelected, usage);
|
||||
final Color bg = UIUtil.getListSelectionBackground();
|
||||
final Color fg = UIUtil.getListSelectionForeground();
|
||||
panel.setBackground(isSelected ? bg : fileBgColor == null ? list.getBackground() : fileBgColor);
|
||||
panel.setForeground(isSelected ? fg : list.getForeground());
|
||||
|
||||
if (usage == null || usageNode instanceof ShowUsagesAction.StringNode) {
|
||||
panel.setLayout(new BorderLayout());
|
||||
if (column == 0) {
|
||||
panel.add(new JLabel(XmlStringUtil.wrapInHtml("<b>" + value + "</b>"), SwingConstants.CENTER));
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
Color panelBackground = isSelected ? bg : fileBgColor == null ? list.getBackground() : fileBgColor;
|
||||
Color panelForeground = isSelected ? fg : list.getForeground();
|
||||
panel.setBackground(panelBackground);
|
||||
panel.setForeground(panelForeground);
|
||||
|
||||
SimpleColoredComponent textChunks = new SimpleColoredComponent();
|
||||
textChunks.setIpad(new Insets(0,0,0,0));
|
||||
textChunks.setIpad(new Insets(0, 0, 0, 0));
|
||||
textChunks.setBorder(null);
|
||||
|
||||
if (usage == null || usageNode instanceof ShowUsagesAction.StringNode) {
|
||||
textChunks.append(value.toString(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
|
||||
}
|
||||
if (usage == ShowUsagesAction.MORE_USAGES_SEPARATOR) {
|
||||
textChunks.append("...<");
|
||||
textChunks.append("more usages", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
textChunks.append(">...");
|
||||
return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
|
||||
}
|
||||
else if (usage == ShowUsagesAction.USAGES_OUTSIDE_SCOPE_SEPARATOR) {
|
||||
textChunks.append("...<");
|
||||
textChunks.append(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
textChunks.append(">...");
|
||||
return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
|
||||
}
|
||||
|
||||
if (column == 0) {
|
||||
GroupNode parent = (GroupNode)usageNode.getParent();
|
||||
appendGroupText(parent, panel, fileBgColor);
|
||||
if (usage == ShowUsagesAction.MORE_USAGES_SEPARATOR) {
|
||||
textChunks.append("...<");
|
||||
textChunks.append("more usages", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
textChunks.append(">...");
|
||||
}
|
||||
}
|
||||
else if (usage != ShowUsagesAction.MORE_USAGES_SEPARATOR) {
|
||||
else if (usage != ShowUsagesAction.MORE_USAGES_SEPARATOR && usage != ShowUsagesAction.USAGES_OUTSIDE_SCOPE_SEPARATOR) {
|
||||
UsagePresentation presentation = usage.getPresentation();
|
||||
TextChunk[] text = presentation.getText();
|
||||
|
||||
@@ -116,6 +128,59 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer {
|
||||
return panel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Component textComponentSpanningWholeRow(@NotNull SimpleColoredComponent chunks,
|
||||
Color panelBackground,
|
||||
Color panelForeground,
|
||||
final int column,
|
||||
@NotNull final JTable table, int row) {
|
||||
final SimpleColoredComponent component = new SimpleColoredComponent() {
|
||||
@Override
|
||||
protected void doPaint(Graphics2D g) {
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
final TableColumnModel columnModel = table.getColumnModel();
|
||||
while (i < column) {
|
||||
offset += columnModel.getColumn(i).getWidth();
|
||||
i++;
|
||||
}
|
||||
g.translate(-offset, 0);
|
||||
|
||||
//if (column == columnModel.getColumnCount()-1) {
|
||||
//}
|
||||
setSize(getWidth()+offset, getHeight()); // should increase the column width so that selection background will be visible even after offset translation
|
||||
|
||||
super.doPaint(g);
|
||||
|
||||
g.translate(+offset, 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
//return super.getPreferredSize();
|
||||
return column == table.getColumnModel().getColumnCount()-1 ? super.getPreferredSize() : new Dimension(0,0);
|
||||
// it should span the whole row, so we can't return any specific value here,
|
||||
// because otherwise it would be used in the "max width" calculation in com.intellij.find.actions.ShowUsagesAction.calcMaxWidth
|
||||
}
|
||||
};
|
||||
|
||||
component.setIpad(new Insets(0,0,0,0));
|
||||
component.setBorder(null);
|
||||
component.setBackground(panelBackground);
|
||||
component.setForeground(panelForeground);
|
||||
|
||||
for (SimpleColoredComponent.ColoredIterator iterator = chunks.iterator(); iterator.hasNext(); ) {
|
||||
iterator.next();
|
||||
String fragment = iterator.getFragment();
|
||||
SimpleTextAttributes attributes = iterator.getTextAttributes();
|
||||
attributes = attributes.derive(attributes.getStyle(), panelForeground, panelBackground, attributes.getWaveColor());
|
||||
component.append(fragment, attributes);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
private static SimpleTextAttributes deriveAttributesWithColor(SimpleTextAttributes attributes, Color fileBgColor) {
|
||||
if (fileBgColor != null) {
|
||||
attributes = attributes.derive(-1,null, fileBgColor,null);
|
||||
|
||||
@@ -205,8 +205,8 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog) {
|
||||
FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
|
||||
public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog, @Nullable("null means default (stored in options)") SearchScope searchScope) {
|
||||
FindUsagesHandler handler = getFindUsagesHandler(psiElement, false);
|
||||
if (handler == null) return;
|
||||
|
||||
boolean singleFile = scopeFile != null;
|
||||
@@ -222,8 +222,8 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
setOpenInNewTab(dialog.isShowInSeparateWindow());
|
||||
|
||||
FindUsagesOptions findUsagesOptions = dialog.calcFindUsagesOptions();
|
||||
if (!showDialog) {
|
||||
findUsagesOptions.searchScope = GlobalSearchScope.projectScope(myProject);
|
||||
if (searchScope != null) {
|
||||
findUsagesOptions.searchScope = searchScope;
|
||||
}
|
||||
|
||||
clearFindingNextUsageInFile();
|
||||
@@ -235,7 +235,7 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
@NotNull FindUsagesOptions findUsagesOptions,
|
||||
PsiFile scopeFile,
|
||||
FileEditor editor) {
|
||||
FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
|
||||
FindUsagesHandler handler = getFindUsagesHandler(psiElement, false);
|
||||
if (handler == null) return;
|
||||
startFindUsages(findUsagesOptions, handler, scopeFile, editor);
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
}
|
||||
}
|
||||
|
||||
public void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
|
||||
public static void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
|
||||
if (targets.length == 0) return;
|
||||
NavigationItem target = targets[0];
|
||||
if (!(target instanceof ConfigurableUsageTarget)) return;
|
||||
@@ -368,9 +368,10 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
final Iterable<PsiElement> elements = ContainerUtil.concat(primaryElements, secondaryElements);
|
||||
|
||||
optionsClone.fastTrack = new SearchRequestCollector(new SearchSession());
|
||||
//if (optionsClone.searchScope instanceof GlobalSearchScope) {
|
||||
// optionsClone.searchScope = optionsClone.searchScope.union(GlobalSearchScope.projectScope(project));
|
||||
//}
|
||||
if (optionsClone.searchScope instanceof GlobalSearchScope) {
|
||||
// we will search in project scope always but warn if some usage is out of scope
|
||||
optionsClone.searchScope = optionsClone.searchScope.union(GlobalSearchScope.projectScope(project));
|
||||
}
|
||||
try {
|
||||
for (final PsiElement element : elements) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@@ -437,14 +438,14 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
throw new AssertionError(handler + " " + findUsagesOptions);
|
||||
}
|
||||
Iterable<PsiElement> allElements = ContainerUtil.concat(primaryElements, secondaryElements);
|
||||
final UsageTarget[] targets = convertToUsageTargets(allElements, findUsagesOptions);
|
||||
final PsiElement2UsageTargetAdapter[] targets = convertToUsageTargets(allElements, findUsagesOptions);
|
||||
myAnotherManager.searchAndShowUsages(targets, new Factory<UsageSearcher>() {
|
||||
@Override
|
||||
public UsageSearcher create() {
|
||||
return createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
|
||||
}
|
||||
}, !toSkipUsagePanelWhenOneUsage, true, createPresentation(primaryElements[0], findUsagesOptions, shouldOpenInNewTab()), null);
|
||||
myHistory.add((ConfigurableUsageTarget)targets[0]);
|
||||
myHistory.add(targets[0]);
|
||||
}
|
||||
|
||||
private static void dropResolveCacheRegularly(ProgressIndicator indicator, @NotNull final Project project) {
|
||||
|
||||
+3
-6
@@ -40,7 +40,6 @@ import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.meta.PsiMetaOwner;
|
||||
import com.intellij.psi.meta.PsiPresentableMetaData;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.ui.ComputableIcon;
|
||||
@@ -219,18 +218,16 @@ public class PsiElement2UsageTargetAdapter
|
||||
return psiElement == null ? UsageViewBundle.message("node.invalid") :
|
||||
FindBundle.message("recent.find.usages.action.popup", StringUtil.capitalize(UsageViewUtil.getType(psiElement)),
|
||||
DescriptiveNameUtil.getDescriptiveName(psiElement),
|
||||
scopeString == null
|
||||
? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName()
|
||||
: scopeString
|
||||
scopeString
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSettings() {
|
||||
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager();
|
||||
PsiElement element = getElement();
|
||||
if (element != null) {
|
||||
findUsagesManager.findUsages(element, null, null, true);
|
||||
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager();
|
||||
findUsagesManager.findUsages(element, null, null, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class PsiElement2UsageTargetComposite extends PsiElement2UsageTargetAdapt
|
||||
PsiElement element = getElement();
|
||||
if (element == null) return;
|
||||
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(element.getProject())).getFindUsagesManager();
|
||||
FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false);
|
||||
FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false);
|
||||
boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage();
|
||||
findUsagesManager.findUsages(myDescriptor.getPrimaryElements(), myDescriptor.getAdditionalElements(), handler, myOptions, skipResultsWithOneUsage);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.search.LexerEditorHighlighterLexer;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
@@ -859,14 +860,19 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
|
||||
findUsages(element, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findUsagesInScope(@NotNull PsiElement element, @NotNull SearchScope searchScope) {
|
||||
myFindUsagesManager.findUsages(element, null, null, false, searchScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findUsages(@NotNull PsiElement element, boolean showDialog) {
|
||||
myFindUsagesManager.findUsages(element, null, null, showDialog);
|
||||
myFindUsagesManager.findUsages(element, null, null, showDialog, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
|
||||
myFindUsagesManager.showSettingsAndFindUsages(targets);
|
||||
FindUsagesManager.showSettingsAndFindUsages(targets);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -882,7 +888,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
|
||||
Document document = editor.getDocument();
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
|
||||
|
||||
myFindUsagesManager.findUsages(element, psiFile, fileEditor, false);
|
||||
myFindUsagesManager.findUsages(element, psiFile, fileEditor, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -60,9 +60,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
myVirtualFile = psiElement.getContainingFile().getVirtualFile();
|
||||
myProject = psiElement.getProject();
|
||||
|
||||
final TemplateLanguageFileViewProvider provider = getViewProvider();
|
||||
assert provider != null;
|
||||
myTemplateDataLanguage = provider.getTemplateDataLanguage();
|
||||
myTemplateDataLanguage = getNotNullViewProvider().getTemplateDataLanguage();
|
||||
}
|
||||
|
||||
private void updateAfterPsiChange() {
|
||||
@@ -115,6 +113,15 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
return provider instanceof TemplateLanguageFileViewProvider ? (TemplateLanguageFileViewProvider)provider : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TemplateLanguageFileViewProvider getNotNullViewProvider() {
|
||||
final FileViewProvider provider = PsiManager.getInstance(myProject).findViewProvider(myVirtualFile);
|
||||
if (provider == null || !(provider instanceof TemplateLanguageFileViewProvider)) {
|
||||
throw new AssertionError("Not a template view provider for " + myVirtualFile + ": " + provider);
|
||||
}
|
||||
return (TemplateLanguageFileViewProvider)provider;
|
||||
}
|
||||
|
||||
private void updateBaseLanguageView() {
|
||||
if (myBaseStructureViewDescriptor == null || !myProject.isOpen()) return;
|
||||
final StructureViewComponent view = (StructureViewComponent)myBaseStructureViewDescriptor.structureView;
|
||||
@@ -158,8 +165,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
public StructureView createStructureView(FileEditor fileEditor, @NotNull Project project) {
|
||||
myFileEditor = fileEditor;
|
||||
List<StructureViewComposite.StructureViewDescriptor> viewDescriptors = new ArrayList<StructureViewComposite.StructureViewDescriptor>();
|
||||
final TemplateLanguageFileViewProvider provider = getViewProvider();
|
||||
assert provider != null;
|
||||
final TemplateLanguageFileViewProvider provider = getNotNullViewProvider();
|
||||
|
||||
final StructureViewComposite.StructureViewDescriptor structureViewDescriptor = createMainView(fileEditor, provider.getPsi(provider.getBaseLanguage()));
|
||||
if (structureViewDescriptor != null) viewDescriptors.add(structureViewDescriptor);
|
||||
|
||||
@@ -580,7 +580,7 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
|
||||
if (offsetInLine > end- lineStartOffset) offsetInLine = end - lineStartOffset;
|
||||
|
||||
CharSequence text = myDocumentWindow.getCharsSequence();
|
||||
return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine, EditorUtil.getTabSize(myDelegate));
|
||||
return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine);
|
||||
}
|
||||
private int calcOffset(int col, int lineNumber, int lineStartOffset) {
|
||||
if (myDocumentWindow.getTextLength() == 0) return 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ public class PsiElementRenameHandler implements RenameHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, Editor editor) {
|
||||
public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, @Nullable Editor editor) {
|
||||
if (element != null && !canRename(project, editor, element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -137,12 +136,12 @@ public class RenameDialog extends RefactoringDialog {
|
||||
return RenamePsiElementProcessor.forElement(myPsiElement).isToSearchInComments(myPsiElement);
|
||||
}
|
||||
|
||||
private String getFullName() {
|
||||
protected String getFullName() {
|
||||
final String name = DescriptiveNameUtil.getDescriptiveName(myPsiElement);
|
||||
return (UsageViewUtil.getType(myPsiElement) + " " + name).trim();
|
||||
}
|
||||
|
||||
private void createNewNameComponent() {
|
||||
protected void createNewNameComponent() {
|
||||
String[] suggestedNames = getSuggestedNames();
|
||||
myOldName = suggestedNames.length > 0 ? suggestedNames[0] : null;
|
||||
myNameSuggestionsField = new NameSuggestionsField(suggestedNames, myProject, FileTypes.PLAIN_TEXT, myEditor) {
|
||||
@@ -341,4 +340,12 @@ public class RenameDialog extends RefactoringDialog {
|
||||
final String newName = getNewName();
|
||||
return RenameUtil.isValidName(myProject, myPsiElement, newName);
|
||||
}
|
||||
|
||||
protected NameSuggestionsField getNameSuggestionsField() {
|
||||
return myNameSuggestionsField;
|
||||
}
|
||||
|
||||
public JCheckBox getCbSearchInComments() {
|
||||
return myCbSearchInComments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +74,6 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
|
||||
if (ApplicationManager.getApplication() != null) { // avoid crash at design time
|
||||
new MyDoClickAction(myBrowseButton).registerShortcut(myComponent);
|
||||
}
|
||||
if (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula()) {
|
||||
setBorder(new EmptyBorder(0, 1, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public final Comp getChildComponent() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.openapi.ui;
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -44,13 +45,13 @@ public class DetailsComponent {
|
||||
private final NonOpaquePanel myBanner;
|
||||
|
||||
private String[] myBannerText;
|
||||
private boolean myDetailsEnabled = true;
|
||||
private boolean myDetailsEnabled = !Registry.is("ide.new.project.settings");
|
||||
private String[] myPrefix;
|
||||
private String[] myText;
|
||||
|
||||
private final Wrapper myContentGutter = new Wrapper();
|
||||
|
||||
private boolean myPaintBorder = true;
|
||||
private boolean myPaintBorder = !Registry.is("ide.new.project.settings");
|
||||
|
||||
public DetailsComponent() {
|
||||
myComponent = new JPanel(new BorderLayout()) {
|
||||
@@ -109,7 +110,9 @@ public class DetailsComponent {
|
||||
myBanner = new NonOpaquePanel(new BorderLayout());
|
||||
myBannerLabel = new Banner();
|
||||
|
||||
myBanner.add(myBannerLabel, BorderLayout.CENTER);
|
||||
if (!Registry.is("ide.new.project.settings")) {
|
||||
myBanner.add(myBannerLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
myEmptyContentLabel = new JLabel("", SwingConstants.CENTER);
|
||||
|
||||
@@ -167,7 +170,11 @@ public class DetailsComponent {
|
||||
myContent.setBorder(new EmptyBorder(UIUtil.PANEL_REGULAR_INSETS));
|
||||
}
|
||||
else {
|
||||
myContent.setBorder(null);
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
myContent.setBorder(new EmptyBorder(16, 10, 16, 10));
|
||||
} else {
|
||||
myContent.setBorder(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ import java.util.Set;
|
||||
public abstract class DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.ui.DialogWrapper");
|
||||
|
||||
public static enum IdeModalityType {
|
||||
public enum IdeModalityType {
|
||||
IDE,
|
||||
PROJECT,
|
||||
MODELESS;
|
||||
@@ -839,7 +839,7 @@ public abstract class DialogWrapper {
|
||||
|
||||
/**
|
||||
* Dispose the wrapped and releases all resources allocated be the wrapper to help
|
||||
* more effecient garbage collection. You should never invoke this method twice or
|
||||
* more efficient garbage collection. You should never invoke this method twice or
|
||||
* invoke any method of the wrapper after invocation of <code>dispose</code>.
|
||||
*
|
||||
* @throws IllegalStateException if the dialog is disposed not on the event dispatch thread
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.navigation.History;
|
||||
@@ -46,6 +47,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.tree.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
@@ -61,7 +63,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
protected static final Icon COPY_ICON = PlatformIcons.COPY_ICON;
|
||||
|
||||
protected NamedConfigurable myCurrentConfigurable;
|
||||
private final Splitter mySplitter = new Splitter(false, .2f);
|
||||
private final JBSplitter mySplitter;
|
||||
|
||||
@NonNls public static final String TREE_OBJECT = "treeObject";
|
||||
@NonNls public static final String TREE_NAME = "treeName";
|
||||
@@ -79,7 +81,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
public void queryPlace(@NotNull final Place place) {
|
||||
}
|
||||
});
|
||||
private JScrollPane myMaster;
|
||||
private JComponent myMaster;
|
||||
|
||||
public void setHistory(final History history) {
|
||||
myHistory = history;
|
||||
@@ -128,6 +130,18 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
|
||||
protected MasterDetailsComponent(MasterDetailsState state) {
|
||||
myState = state;
|
||||
|
||||
mySplitter = new JBSplitter(false, .2f);
|
||||
mySplitter.setSplitterProportionKey("ProjectStructure.SecondLevelElements");
|
||||
mySplitter.setHonorComponentsMinimumSize(true);
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
mySplitter.setDividerWidth(1);
|
||||
mySplitter.setShowDividerIcon(false);
|
||||
mySplitter.getDivider().setBackground(Gray._153.withAlpha(128));
|
||||
mySplitter.setShowDividerControls(false);
|
||||
mySplitter.setOrientation(mySplitter.getOrientation());
|
||||
}
|
||||
|
||||
installAutoScroll();
|
||||
reInitWholePanelIfNeeded();
|
||||
}
|
||||
@@ -163,8 +177,18 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
}
|
||||
};
|
||||
|
||||
left.add(myNorthPanel, BorderLayout.NORTH);
|
||||
myMaster = ScrollPaneFactory.createScrollPane(myTree);
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree);
|
||||
DefaultActionGroup group = createToolbarActionGroup();
|
||||
if (group != null) {
|
||||
decorator.setActionGroup(group);
|
||||
}
|
||||
//left.add(myNorthPanel, BorderLayout.NORTH);
|
||||
myMaster = decorator.setPanelBorder(new EmptyBorder(0, 0, 0, 0)).createPanel();
|
||||
} else {
|
||||
left.add(myNorthPanel, BorderLayout.NORTH);
|
||||
myMaster = ScrollPaneFactory.createScrollPane(myTree);
|
||||
}
|
||||
left.add(myMaster, BorderLayout.CENTER);
|
||||
mySplitter.setFirstComponent(left);
|
||||
|
||||
@@ -245,7 +269,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
return myHistory == null || !myHistory.isNavigatingNow();
|
||||
}
|
||||
|
||||
private void initToolbar() {
|
||||
protected DefaultActionGroup createToolbarActionGroup() {
|
||||
final ArrayList<AnAction> actions = createActions(false);
|
||||
if (actions != null) {
|
||||
final DefaultActionGroup group = new DefaultActionGroup();
|
||||
@@ -257,6 +281,14 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
group.add(action);
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void initToolbar() {
|
||||
DefaultActionGroup group = createToolbarActionGroup();
|
||||
if (group != null) {
|
||||
final JComponent component = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
|
||||
myNorthPanel.add(component, BorderLayout.NORTH);
|
||||
}
|
||||
@@ -270,6 +302,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
|
||||
return new Dimension(800, 600);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JComponent createComponent() {
|
||||
reInitWholePanelIfNeeded();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.components.panels.OpaquePanel;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -24,16 +26,43 @@ import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import java.awt.*;
|
||||
|
||||
import static javax.swing.SwingConstants.CENTER;
|
||||
import static javax.swing.SwingConstants.LEFT;
|
||||
|
||||
public abstract class GroupedElementsRenderer {
|
||||
public static final Color POPUP_SEPARATOR_FOREGROUND = new JBColor(Color.gray.brighter(), Gray._43);
|
||||
public static final Color POPUP_SEPARATOR_TEXT_FOREGROUND = Color.gray;
|
||||
public static final Color SELECTED_FRAME_FOREGROUND = Color.black;
|
||||
|
||||
protected SeparatorWithText mySeparatorComponent = new SeparatorWithText();
|
||||
protected SeparatorWithText mySeparatorComponent = new SeparatorWithText() {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
g.setColor(POPUP_SEPARATOR_FOREGROUND);
|
||||
Rectangle viewR = new Rectangle(0, getVgap(), getWidth() - 1, getHeight() - getVgap() - 1);
|
||||
Rectangle iconR = new Rectangle();
|
||||
Rectangle textR = new Rectangle();
|
||||
String s = SwingUtilities
|
||||
.layoutCompoundLabel(g.getFontMetrics(), getCaption(), null, CENTER,
|
||||
LEFT,
|
||||
CENTER,
|
||||
LEFT,
|
||||
viewR, iconR, textR, 0);
|
||||
GraphicsUtil.setupAAPainting(g);
|
||||
g.setColor(Gray._255.withAlpha(80));
|
||||
g.drawString(s, textR.x + 10, textR.y + 1 + g.getFontMetrics().getAscent());
|
||||
g.setColor(new Color(0x5F6D7B));
|
||||
g.drawString(s, textR.x + 10, textR.y + g.getFontMetrics().getAscent());
|
||||
} else {
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected JComponent myComponent;
|
||||
protected MyComponent myRendererComponent;
|
||||
|
||||
protected ErrorLabel myTextLabel;
|
||||
protected JLabel myTextLabel;
|
||||
|
||||
|
||||
public GroupedElementsRenderer() {
|
||||
@@ -58,14 +87,16 @@ public abstract class GroupedElementsRenderer {
|
||||
|
||||
myTextLabel.setIcon(icon);
|
||||
myTextLabel.setDisabledIcon(disabledIcon);
|
||||
if (myTextLabel instanceof EngravedLabel) {
|
||||
((EngravedLabel)myTextLabel).setShadowColor(isSelected ? UIUtil.getTreeSelectionBackground() : null);
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
myComponent.setBorder(getSelectedBorder());
|
||||
//myComponent.setBorder(getSelectedBorder());
|
||||
setSelected(myComponent);
|
||||
setSelected(myTextLabel);
|
||||
}
|
||||
else {
|
||||
myComponent.setBorder(getBorder());
|
||||
} else {
|
||||
//myComponent.setBorder(getBorder());
|
||||
setDeselected(myComponent);
|
||||
setDeselected(myTextLabel);
|
||||
}
|
||||
@@ -98,7 +129,7 @@ public abstract class GroupedElementsRenderer {
|
||||
|
||||
protected final void setDeselected(JComponent aComponent) {
|
||||
aComponent.setBackground(getBackground());
|
||||
aComponent.setForeground(getForeground());
|
||||
aComponent.setForeground(Registry.is("ide.new.project.settings") ? Gray._60 : getForeground());
|
||||
}
|
||||
|
||||
protected abstract Color getSelectionBackground();
|
||||
@@ -139,12 +170,12 @@ public abstract class GroupedElementsRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Color getBackground() {
|
||||
protected Color getBackground() {
|
||||
return UIUtil.getListBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Color getForeground() {
|
||||
protected Color getForeground() {
|
||||
return UIUtil.getListForeground();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,8 @@ import com.intellij.util.ui.UIUtil;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import static javax.swing.SwingConstants.*;
|
||||
import static javax.swing.SwingConstants.CENTER;
|
||||
import static javax.swing.SwingConstants.LEFT;
|
||||
|
||||
public class SeparatorWithText extends JComponent {
|
||||
|
||||
@@ -34,11 +35,11 @@ public class SeparatorWithText extends JComponent {
|
||||
setFont(getFont().deriveFont(Font.BOLD));
|
||||
}
|
||||
|
||||
private static int getVgap() {
|
||||
protected static int getVgap() {
|
||||
return UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
|
||||
}
|
||||
|
||||
private static int getHgap() {
|
||||
protected static int getHgap() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -109,6 +110,10 @@ public class SeparatorWithText extends JComponent {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getCaption() {
|
||||
return myCaption;
|
||||
}
|
||||
|
||||
public void setCaption(String captionAboveOf) {
|
||||
myCaption = captionAboveOf;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbarPosition;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
@@ -296,7 +293,9 @@ public abstract class ToolbarDecorator implements CommonActionsPanel.ListenerFac
|
||||
public ToolbarDecorator setActionGroup(@NotNull ActionGroup actionGroup) {
|
||||
AnAction[] actions = actionGroup.getChildren(null);
|
||||
for (AnAction action : actions) {
|
||||
addExtraAction(AnActionButton.fromAction(action));
|
||||
if (!(action instanceof Separator)) {
|
||||
addExtraAction(AnActionButton.fromAction(action));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -753,6 +753,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
|
||||
UIUtil.setLineStyleAngled(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T> T[] getSelectedNodes(Class<T> nodeType, @Nullable NodeFilter<T> filter) {
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
if (paths == null) return (T[])Array.newInstance(nodeType, 0);
|
||||
|
||||
@@ -488,8 +488,6 @@ public final class EditorUtil {
|
||||
}
|
||||
|
||||
if (editor == null || useOptimization) {
|
||||
int shift = 0;
|
||||
|
||||
Document document = editor == null ? null : editor.getDocument();
|
||||
if (document != null && start < offset-1 && document.getLineNumber(start) != document.getLineNumber(offset-1)) {
|
||||
String editorInfo = editor instanceof EditorImpl ? ". Editor info: " + ((EditorImpl)editor).dumpState() : "";
|
||||
@@ -504,6 +502,7 @@ public final class EditorUtil {
|
||||
LOG, "detected incorrect offset -> column number calculation",
|
||||
"start: " + start + ", given offset: " + offset+", given tab size: " + tabSize + ". "+documentInfo+ editorInfo);
|
||||
}
|
||||
int shift = 0;
|
||||
if (hasTabs) {
|
||||
for (int i = start; i < offset; i++) {
|
||||
char c = text.charAt(i);
|
||||
|
||||
@@ -561,7 +561,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
myEditor.updateCaretCursor();
|
||||
requestRepaint(oldInfo);
|
||||
|
||||
if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(myEditor)) {
|
||||
if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(this)) {
|
||||
int lineToUse = myVisibleCaret.line - 1;
|
||||
if (lineToUse >= 0) {
|
||||
final VisualPosition visualPosition = new VisualPosition(lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse));
|
||||
@@ -1451,6 +1451,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset;
|
||||
}
|
||||
|
||||
public EditorImpl getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulates information about target vertical range info - its <code>'y'</code> coordinate and height in pixels.
|
||||
*/
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl.softwrap;
|
||||
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.SoftWrap;
|
||||
import com.intellij.openapi.editor.SoftWrapModel;
|
||||
import com.intellij.openapi.editor.impl.CaretImpl;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
|
||||
/**
|
||||
@@ -48,18 +48,18 @@ public class SoftWrapHelper {
|
||||
* @return <code>true</code> if caret offset of the given editor points to visual position that belongs to
|
||||
* visual line where soft wrap end is located
|
||||
*/
|
||||
public static boolean isCaretAfterSoftWrap(EditorImpl editor) {
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
if (!caretModel.isUpToDate()) {
|
||||
public static boolean isCaretAfterSoftWrap(CaretImpl caret) {
|
||||
if (!caret.isUpToDate()) {
|
||||
return false;
|
||||
}
|
||||
EditorImpl editor = caret.getEditor();
|
||||
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
|
||||
int offset = caretModel.getOffset();
|
||||
int offset = caret.getOffset();
|
||||
SoftWrap softWrap = softWrapModel.getSoftWrap(offset);
|
||||
if (softWrap == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return editor.offsetToVisualLine(offset) == caretModel.getVisualPosition().line;
|
||||
return editor.offsetToVisualLine(offset) == caret.getVisualPosition().line;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,11 @@
|
||||
package com.intellij.ui.popup.list;
|
||||
|
||||
import com.intellij.openapi.ui.popup.ListItemDescriptor;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.EngravedLabel;
|
||||
import com.intellij.ui.ErrorLabel;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.GroupedElementsRenderer;
|
||||
import com.intellij.ui.components.panels.OpaquePanel;
|
||||
|
||||
@@ -55,15 +58,21 @@ public class GroupedItemsListRenderer extends GroupedElementsRenderer.List imple
|
||||
|
||||
@Override
|
||||
protected JComponent createItemComponent() {
|
||||
myTextLabel = new ErrorLabel();
|
||||
myTextLabel.setOpaque(true);
|
||||
myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
if (Registry.is("ide.new.project.settings")) {
|
||||
myTextLabel = new EngravedLabel();
|
||||
myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD));
|
||||
myTextLabel.setForeground(Gray._240);
|
||||
} else {
|
||||
myTextLabel = new ErrorLabel();
|
||||
myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
myTextLabel.setOpaque(true);
|
||||
return layoutComponent(myTextLabel);
|
||||
}
|
||||
|
||||
protected final JComponent layoutComponent(JComponent middleItemComponent) {
|
||||
JPanel result = new OpaquePanel(new BorderLayout(4, 4), Color.white);
|
||||
JPanel result = new OpaquePanel(Registry.is("ide.new.project.settings") ? new BorderLayout(0, 0) : new BorderLayout(4, 4), Color.white);
|
||||
|
||||
myNextStepLabel = new JLabel();
|
||||
myNextStepLabel.setOpaque(true);
|
||||
|
||||
@@ -138,6 +138,8 @@ button.configure=&Configure VCS...
|
||||
action.name.rollback=Rollback
|
||||
command.name.rollback.change=Rollback Change
|
||||
action.name.show.difference=Show Difference
|
||||
tooltip.text.line.before.deleted=Line before {0} deleted
|
||||
tooltip.text.lines.before.deleted={1} lines before {0} deleted
|
||||
tooltip.text.line.changed=Line {0} changed
|
||||
tooltip.text.lines.changed=Lines {0}-{1} changed
|
||||
dialog.title.diff.for.range=Diff for Range
|
||||
|
||||
@@ -402,3 +402,5 @@ console.too.much.text.buffer.ratio=10
|
||||
console.too.much.text.buffer.ratio.description=Used for disabling of console processing(console filters for highlights, foldings...),\n\
|
||||
when there is too much of text to process.\n\
|
||||
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
|
||||
ide.new.project.settings=false
|
||||
ide.new.project.settings.description=Temporary key for new project settings dialog UI
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.editor.impl.AbstractEditorTest;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.testFramework.EditorTestUtil;
|
||||
import com.intellij.testFramework.TestFileType;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
@@ -305,4 +306,18 @@ public class EditorMultiCaretTest extends AbstractEditorTest {
|
||||
"brown\n" +
|
||||
"fox");
|
||||
}
|
||||
|
||||
public void testCaretPositionsRecalculationOnDocumentChange() throws Exception {
|
||||
init("\n" +
|
||||
"<selection><caret>word</selection>\n" +
|
||||
"some long prefix <selection><caret>word</selection>-suffix", TestFileType.TEXT);
|
||||
EditorTestUtil.configureSoftWraps(myEditor, 17); // wrapping right before 'word-suffix'
|
||||
|
||||
delete();
|
||||
|
||||
checkResultByText("\n" +
|
||||
"<caret>\n" +
|
||||
"some long prefix <caret>-suffix");
|
||||
verifySoftWrapPositions(19);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -282,7 +282,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
|
||||
}
|
||||
}
|
||||
|
||||
fireErrors(errors);
|
||||
onModuleLoadErrors(errors);
|
||||
|
||||
showUnknownModuleTypeNotification(modulesWithUnknownTypes);
|
||||
|
||||
@@ -321,7 +321,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
|
||||
}
|
||||
}
|
||||
|
||||
private void fireErrors(final List<ModuleLoadingErrorDescription> errors) {
|
||||
protected void onModuleLoadErrors(final List<ModuleLoadingErrorDescription> errors) {
|
||||
if (errors.isEmpty()) return;
|
||||
|
||||
myModuleModel.myModulesCache = null;
|
||||
@@ -337,6 +337,10 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
|
||||
}
|
||||
}
|
||||
|
||||
fireModuleLoadErrors(errors);
|
||||
}
|
||||
|
||||
protected void fireModuleLoadErrors(List<ModuleLoadingErrorDescription> errors) {
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
throw new RuntimeException(errors.get(0).getDescription());
|
||||
}
|
||||
|
||||
+3
@@ -21,6 +21,9 @@ public abstract class ServerRuntimeInstance<D extends DeploymentConfiguration> {
|
||||
return getDeploymentName(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getDeploymentName(com.intellij.remoteServer.configuration.deployment.DeploymentSource, D configuration)} instead
|
||||
*/
|
||||
@NotNull
|
||||
public String getDeploymentName(@NotNull DeploymentSource source) {
|
||||
return source.getPresentableName();
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.debugger;
|
||||
|
||||
import com.intellij.util.Url;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public interface HasUrl {
|
||||
@NotNull
|
||||
Url getUrl();
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.debugger.sourcemap.SourceMap;
|
||||
|
||||
public interface Script extends UserDataHolderEx {
|
||||
public interface Script extends UserDataHolderEx, HasUrl {
|
||||
void setSourceMap(SourceMap sourceMap);
|
||||
|
||||
enum Type {
|
||||
|
||||
+17
-3
@@ -60,9 +60,23 @@ class FieldProcessor<T> {
|
||||
|
||||
private MethodHandler processFieldGetterMethod(Method m, String fieldName) {
|
||||
Type genericReturnType = m.getGenericReturnType();
|
||||
boolean nullable = m.getAnnotation(JsonNullable.class) != null ||
|
||||
(genericReturnType == String.class && ((m.getAnnotation(JsonField.class) != null && m.getAnnotation(JsonField.class).optional())
|
||||
|| m.getAnnotation(JsonOptionalField.class) != null));
|
||||
boolean nullable;
|
||||
if (m.getAnnotation(JsonNullable.class) != null) {
|
||||
nullable = true;
|
||||
}
|
||||
else if (genericReturnType == String.class || genericReturnType == Enum.class) {
|
||||
JsonField jsonField = m.getAnnotation(JsonField.class);
|
||||
if (jsonField != null) {
|
||||
nullable = jsonField.optional() && !jsonField.allowAnyPrimitiveValue() && !jsonField.allowAnyPrimitiveValueAndMap();
|
||||
}
|
||||
else {
|
||||
nullable = m.getAnnotation(JsonOptionalField.class) != null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nullable = false;
|
||||
}
|
||||
|
||||
ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, m);
|
||||
if (fieldTypeParser != InterfaceReader.VOID_PARSER) {
|
||||
fieldLoaders.add(new FieldLoader(fieldName, fieldTypeParser));
|
||||
|
||||
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.usages.impl;
|
||||
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.util.ProgressWrapper;
|
||||
import com.intellij.openapi.progress.util.TooManyUsagesStatus;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.ui.HyperlinkAdapter;
|
||||
import com.intellij.usageView.UsageViewBundle;
|
||||
import com.intellij.usages.*;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ui.RangeBlinker;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
class SearchForUsagesRunnable implements Runnable {
|
||||
@NonNls private static final String FIND_OPTIONS_HREF_TARGET = "FindOptions";
|
||||
@NonNls private static final String SEARCH_IN_PROJECT_HREF_TARGET = "SearchInProject";
|
||||
@NonNls private static final String LARGE_FILES_HREF_TARGET = "LargeFiles";
|
||||
private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0);
|
||||
private final AtomicReference<Usage> myFirstUsage = new AtomicReference<Usage>();
|
||||
@NotNull
|
||||
private final Project myProject;
|
||||
private final AtomicReference<UsageViewImpl> myUsageViewRef;
|
||||
private final UsageViewPresentation myPresentation;
|
||||
private final UsageTarget[] mySearchFor;
|
||||
private final Factory<UsageSearcher> mySearcherFactory;
|
||||
private final FindUsagesProcessPresentation myProcessPresentation;
|
||||
@NotNull private final SearchScope mySearchScope;
|
||||
private final UsageViewManager.UsageViewStateListener myListener;
|
||||
private final UsageViewManagerImpl myUsageViewManager;
|
||||
private final AtomicInteger myOutOfScopeUsages = new AtomicInteger();
|
||||
|
||||
SearchForUsagesRunnable(@NotNull UsageViewManagerImpl usageViewManager,
|
||||
@NotNull Project project,
|
||||
@NotNull AtomicReference<UsageViewImpl> usageViewRef,
|
||||
@NotNull UsageViewPresentation presentation,
|
||||
@NotNull UsageTarget[] searchFor,
|
||||
@NotNull Factory<UsageSearcher> searcherFactory,
|
||||
@NotNull FindUsagesProcessPresentation processPresentation,
|
||||
@NotNull SearchScope scope,
|
||||
@Nullable UsageViewManager.UsageViewStateListener listener) {
|
||||
myProject = project;
|
||||
myUsageViewRef = usageViewRef;
|
||||
myPresentation = presentation;
|
||||
mySearchFor = searchFor;
|
||||
mySearcherFactory = searcherFactory;
|
||||
myProcessPresentation = processPresentation;
|
||||
mySearchScope = scope;
|
||||
myListener = listener;
|
||||
myUsageViewManager = usageViewManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String createOptionsHtml(@NonNls UsageTarget[] searchFor) {
|
||||
KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(searchFor);
|
||||
String shortcutText = "";
|
||||
if (shortcut != null) {
|
||||
shortcutText = " (" + KeymapUtil.getShortcutText(shortcut) + ")";
|
||||
}
|
||||
return "<a href='" + FIND_OPTIONS_HREF_TARGET + "'>Find Options...</a>" + shortcutText;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String createSearchInProjectHtml() {
|
||||
return "<a href='" + SEARCH_IN_PROJECT_HREF_TARGET + "'>Search in Project</a>";
|
||||
}
|
||||
|
||||
private static void notifyByFindBalloon(final HyperlinkListener listener,
|
||||
@NotNull final MessageType info,
|
||||
@NotNull FindUsagesProcessPresentation processPresentation,
|
||||
@NotNull final Project project,
|
||||
@NotNull final List<String> lines) {
|
||||
com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered
|
||||
|
||||
final Collection<PsiFile> largeFiles = processPresentation.getLargeFiles();
|
||||
List<String> resultLines = new ArrayList<String>(lines);
|
||||
HyperlinkListener resultListener = listener;
|
||||
if (!largeFiles.isEmpty()) {
|
||||
String shortMessage = "(<a href='" + LARGE_FILES_HREF_TARGET + "'>"
|
||||
+ UsageViewBundle.message("large.files.were.ignored", largeFiles.size()) + "</a>)";
|
||||
|
||||
resultLines.add(shortMessage);
|
||||
resultListener = new HyperlinkAdapter(){
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
if (e.getDescription().equals(LARGE_FILES_HREF_TARGET)) {
|
||||
String detailedMessage = detailedLargeFilesMessage(largeFiles);
|
||||
List<String> strings = new ArrayList<String>(lines);
|
||||
strings.add(detailedMessage);
|
||||
ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
|
||||
}
|
||||
else if (listener != null) {
|
||||
listener.hyperlinkUpdate(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String wrapInHtml(@NotNull List<String> strings) {
|
||||
return XmlStringUtil.wrapInHtml(StringUtil.join(strings, "<br>"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String detailedLargeFilesMessage(@NotNull Collection<PsiFile> largeFiles) {
|
||||
String message = "";
|
||||
if (largeFiles.size() == 1) {
|
||||
final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile();
|
||||
message += "File " + presentableFileInfo(vFile) + " is ";
|
||||
}
|
||||
else {
|
||||
message += "Files<br> ";
|
||||
|
||||
int counter = 0;
|
||||
for (PsiFile file : largeFiles) {
|
||||
final VirtualFile vFile = file.getVirtualFile();
|
||||
message += presentableFileInfo(vFile) + "<br> ";
|
||||
if (counter++ > 10) break;
|
||||
}
|
||||
|
||||
message += "are ";
|
||||
}
|
||||
|
||||
message += "too large and cannot be scanned";
|
||||
return message;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String presentableFileInfo(@NotNull VirtualFile vFile) {
|
||||
return getPresentablePath(vFile)
|
||||
+ " ("
|
||||
+ UsageViewManagerImpl.presentableSize(UsageViewManagerImpl.getFileLength(vFile))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getPresentablePath(@NotNull final VirtualFile virtualFile) {
|
||||
return "'" + ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return virtualFile.getPresentableUrl();
|
||||
}
|
||||
}) + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private HyperlinkListener createGotToOptionsListener(@NotNull final UsageTarget[] targets) {
|
||||
return new HyperlinkAdapter() {
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
if (e.getDescription().equals(FIND_OPTIONS_HREF_TARGET)) {
|
||||
FindManager.getInstance(myProject).showSettingsAndFindUsages(targets);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@NotNull
|
||||
private HyperlinkListener createSearchInProjectListener() {
|
||||
return new HyperlinkAdapter() {
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
if (e.getDescription().equals(SEARCH_IN_PROJECT_HREF_TARGET)) {
|
||||
PsiElement psiElement = getPsiElement(mySearchFor);
|
||||
if (psiElement != null) {
|
||||
FindManager.getInstance(myProject).findUsagesInScope(psiElement, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static PsiElement getPsiElement(UsageTarget[] searchFor) {
|
||||
if (!(searchFor[0] instanceof PsiElementUsageTarget)) return null;
|
||||
return ((PsiElementUsageTarget)searchFor[0]).getElement();
|
||||
}
|
||||
|
||||
private static void flashUsageScriptaculously(@NotNull final Usage usage) {
|
||||
if (!(usage instanceof UsageInfo2UsageAdapter)) {
|
||||
return;
|
||||
}
|
||||
UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage;
|
||||
|
||||
Editor editor = usageInfo.openTextEditor(true);
|
||||
if (editor == null) return;
|
||||
TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
|
||||
|
||||
RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6);
|
||||
List<Segment> segments = new ArrayList<Segment>();
|
||||
CommonProcessors.CollectProcessor<Segment> processor = new CommonProcessors.CollectProcessor<Segment>(segments);
|
||||
usageInfo.processRangeMarkers(processor);
|
||||
rangeBlinker.resetMarkers(segments);
|
||||
rangeBlinker.startBlinking();
|
||||
}
|
||||
|
||||
private UsageViewImpl getUsageView(ProgressIndicator indicator) {
|
||||
UsageViewImpl usageView = myUsageViewRef.get();
|
||||
if (usageView != null) return usageView;
|
||||
int usageCount = myUsageCountWithoutDefinition.get();
|
||||
if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
|
||||
usageView.associateProgress(indicator);
|
||||
if (myUsageViewRef.compareAndSet(null, usageView)) {
|
||||
openView(usageView);
|
||||
final Usage firstUsage = myFirstUsage.get();
|
||||
if (firstUsage != null) {
|
||||
final UsageViewImpl finalUsageView = usageView;
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finalUsageView.appendUsage(firstUsage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Disposer.dispose(usageView);
|
||||
}
|
||||
return myUsageViewRef.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void openView(@NotNull final UsageViewImpl usageView) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
myUsageViewManager.addContent(usageView, myPresentation);
|
||||
if (myListener != null) {
|
||||
myListener.usageViewCreated(usageView);
|
||||
}
|
||||
myUsageViewManager.showToolWindow(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AtomicBoolean findUsagesStartedShown = new AtomicBoolean();
|
||||
searchUsages(findUsagesStartedShown);
|
||||
endSearchForUsages(findUsagesStartedShown);
|
||||
}
|
||||
|
||||
private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
|
||||
ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
|
||||
TooManyUsagesStatus.createFor(indicator);
|
||||
Alarm findUsagesStartedBalloon = new Alarm();
|
||||
findUsagesStartedBalloon.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, myProject,
|
||||
Collections.singletonList(UsageViewManagerImpl.getProgressTitle(myPresentation)));
|
||||
findStartedBalloonShown.set(true);
|
||||
}
|
||||
}, 300, ModalityState.NON_MODAL);
|
||||
UsageSearcher usageSearcher = mySearcherFactory.create();
|
||||
|
||||
usageSearcher.generate(new Processor<Usage>() {
|
||||
@Override
|
||||
public boolean process(final Usage usage) {
|
||||
ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
|
||||
if (indicator != null && indicator.isCanceled()) return false;
|
||||
|
||||
if (!UsageViewManagerImpl.isInScope(usage, mySearchScope)) {
|
||||
myOutOfScopeUsages.incrementAndGet();
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean incrementCounter = !UsageViewManager.isSelfUsage(usage, mySearchFor);
|
||||
|
||||
if (incrementCounter) {
|
||||
final int usageCount = myUsageCountWithoutDefinition.incrementAndGet();
|
||||
if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
myFirstUsage.compareAndSet(null, usage);
|
||||
}
|
||||
|
||||
final UsageViewImpl usageView = getUsageView(indicator);
|
||||
|
||||
TooManyUsagesStatus tooManyUsagesStatus;
|
||||
if (usageCount > UsageLimitUtil.USAGES_LIMIT && (tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator)).switchTooManyUsagesStatus()) {
|
||||
UsageViewManagerImpl.showTooManyUsagesWarning(myProject, tooManyUsagesStatus, indicator, myPresentation, usageCount, usageView);
|
||||
}
|
||||
|
||||
if (usageView != null) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
usageView.appendUsage(usage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return indicator == null || !indicator.isCanceled();
|
||||
}
|
||||
});
|
||||
if (getUsageView(indicator) != null) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myUsageViewManager.showToolWindow(true);
|
||||
}
|
||||
}, myProject.getDisposed());
|
||||
}
|
||||
Disposer.dispose(findUsagesStartedBalloon);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (findStartedBalloonShown.get()) {
|
||||
Balloon balloon = ToolWindowManager.getInstance(myProject).getToolWindowBalloon(ToolWindowId.FIND);
|
||||
if (balloon != null) {
|
||||
balloon.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, myProject.getDisposed());
|
||||
}
|
||||
|
||||
private void endSearchForUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
|
||||
assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
|
||||
int usageCount = myUsageCountWithoutDefinition.get();
|
||||
if (usageCount == 0 && myProcessPresentation.isShowNotFoundMessage()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
|
||||
final String message = UsageViewBundle.message("dialog.no.usages.found.in",
|
||||
StringUtil.decapitalize(myPresentation.getUsagesString()),
|
||||
myPresentation.getScopeText());
|
||||
|
||||
if (notFoundActions.isEmpty()) {
|
||||
List<String> lines = new ArrayList<String>();
|
||||
lines.add(StringUtil.escapeXml(message));
|
||||
if (myOutOfScopeUsages.get() != 0) {
|
||||
lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
|
||||
}
|
||||
if (myProcessPresentation.isShowFindOptionsPrompt()) {
|
||||
lines.add(createOptionsHtml(mySearchFor));
|
||||
}
|
||||
MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
|
||||
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
|
||||
type, myProcessPresentation, myProject, lines);
|
||||
findStartedBalloonShown.set(false);
|
||||
}
|
||||
else {
|
||||
List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
|
||||
titles.add(UsageViewBundle.message("dialog.button.ok"));
|
||||
for (Action action : notFoundActions) {
|
||||
Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
|
||||
if (value == null) value = action.getValue(Action.NAME);
|
||||
|
||||
titles.add((String)value);
|
||||
}
|
||||
|
||||
int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
|
||||
ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
|
||||
|
||||
if (option > 0) {
|
||||
notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
else if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Usage usage = myFirstUsage.get();
|
||||
if (usage.canNavigate()) {
|
||||
usage.navigate(true);
|
||||
flashUsageScriptaculously(usage);
|
||||
}
|
||||
List<String> lines = new ArrayList<String>();
|
||||
|
||||
lines.add("Only one usage found.");
|
||||
if (myOutOfScopeUsages.get() != 0) {
|
||||
lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
|
||||
}
|
||||
lines.add(createOptionsHtml(mySearchFor));
|
||||
MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
|
||||
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
|
||||
type, myProcessPresentation, myProject,
|
||||
lines);
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
else {
|
||||
final UsageViewImpl usageView = myUsageViewRef.get();
|
||||
if (usageView != null) {
|
||||
usageView.drainQueuedUsageNodes();
|
||||
usageView.setSearchInProgress(false);
|
||||
}
|
||||
|
||||
final List<String> lines;
|
||||
final HyperlinkListener hyperlinkListener;
|
||||
if (myOutOfScopeUsages.get() == 0 || getPsiElement(mySearchFor)==null) {
|
||||
lines = Collections.emptyList();
|
||||
hyperlinkListener = null;
|
||||
}
|
||||
else {
|
||||
lines = Arrays.asList(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope), createSearchInProjectHtml());
|
||||
hyperlinkListener = createSearchInProjectListener();
|
||||
}
|
||||
|
||||
if (!myProcessPresentation.getLargeFiles().isEmpty() || myOutOfScopeUsages.get() != 0) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
|
||||
notifyByFindBalloon(hyperlinkListener, type, myProcessPresentation, myProject, lines);
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
}
|
||||
|
||||
if (myListener != null) {
|
||||
myListener.findingUsagesFinished(myUsageViewRef.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,59 +15,37 @@
|
||||
*/
|
||||
package com.intellij.usages.impl;
|
||||
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.SearchInBackgroundOption;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.actionSystem.DataSink;
|
||||
import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.progress.util.ProgressWrapper;
|
||||
import com.intellij.openapi.progress.util.TooManyUsagesStatus;
|
||||
import com.intellij.openapi.project.DumbModeAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.HyperlinkAdapter;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.usageView.UsageViewBundle;
|
||||
import com.intellij.usages.*;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ui.RangeBlinker;
|
||||
import com.intellij.usages.rules.PsiElementUsage;
|
||||
import com.intellij.usages.rules.UsageInFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -76,8 +54,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class UsageViewManagerImpl extends UsageViewManager {
|
||||
private final Project myProject;
|
||||
private static final Key<UsageView> USAGE_VIEW_KEY = Key.create("USAGE_VIEW");
|
||||
@NonNls private static final String LARGE_FILES_HREF_TARGET = "LargeFiles";
|
||||
@NonNls private static final String FIND_OPTIONS_HREF_TARGET = "FindOptions";
|
||||
|
||||
public UsageViewManagerImpl(@NotNull Project project) {
|
||||
myProject = project;
|
||||
@@ -113,7 +89,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
return showUsages(searchedFor, foundUsages, presentation, null);
|
||||
}
|
||||
|
||||
private void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) {
|
||||
void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) {
|
||||
Content content = com.intellij.usageView.UsageViewManager.getInstance(myProject).addContent(
|
||||
presentation.getTabText(),
|
||||
presentation.getTabName(),
|
||||
@@ -146,14 +122,26 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
@NotNull final UsageViewPresentation presentation,
|
||||
@NotNull final FindUsagesProcessPresentation processPresentation,
|
||||
@Nullable final UsageViewStateListener listener) {
|
||||
final SearchScope searchScope = getSearchScope(searchFor);
|
||||
return doSearchAndShow(searchFor, searcherFactory, presentation, processPresentation, listener, searchScope);
|
||||
}
|
||||
|
||||
UsageView doSearchAndShow(@NotNull final UsageTarget[] searchFor,
|
||||
@NotNull final Factory<UsageSearcher> searcherFactory,
|
||||
@NotNull final UsageViewPresentation presentation,
|
||||
@NotNull final FindUsagesProcessPresentation processPresentation,
|
||||
@Nullable final UsageViewStateListener listener,
|
||||
@NotNull final SearchScope searchScope) {
|
||||
final AtomicReference<UsageViewImpl> usageViewRef = new AtomicReference<UsageViewImpl>();
|
||||
|
||||
Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) {
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
new SearchForUsagesRunnable(UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory,
|
||||
processPresentation, listener).run();
|
||||
new SearchForUsagesRunnable(UsageViewManagerImpl.this, UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory,
|
||||
processPresentation, searchScope, listener).run();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DumbModeAction getDumbModeAction() {
|
||||
return DumbModeAction.CANCEL;
|
||||
@@ -170,6 +158,22 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
return usageViewRef.get();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SearchScope getSearchScope(@NotNull UsageTarget[] searchFor) {
|
||||
UsageTarget target = searchFor[0];
|
||||
if (target instanceof TypeSafeDataProvider) {
|
||||
final SearchScope[] scope = new SearchScope[1];
|
||||
((TypeSafeDataProvider)target).calcData(UsageView.USAGE_SCOPE, new DataSink() {
|
||||
@Override
|
||||
public <T> void put(DataKey<T> key, T data) {
|
||||
scope[0] = (SearchScope)data;
|
||||
}
|
||||
});
|
||||
return scope[0];
|
||||
}
|
||||
return GlobalSearchScope.projectScope(myProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchAndShowUsages(@NotNull UsageTarget[] searchFor,
|
||||
@NotNull Factory<UsageSearcher> searcherFactory,
|
||||
@@ -197,7 +201,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
return StringUtil.escapeXml(result);
|
||||
}
|
||||
|
||||
private void showToolWindow(boolean activateWindow) {
|
||||
void showToolWindow(boolean activateWindow) {
|
||||
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND);
|
||||
toolWindow.show(null);
|
||||
if (activateWindow && !toolWindow.isActive()) {
|
||||
@@ -238,304 +242,6 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
});
|
||||
}
|
||||
|
||||
private class SearchForUsagesRunnable implements Runnable {
|
||||
private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0);
|
||||
private final AtomicReference<Usage> myFirstUsage = new AtomicReference<Usage>();
|
||||
@NotNull
|
||||
private final Project myProject;
|
||||
private final AtomicReference<UsageViewImpl> myUsageViewRef;
|
||||
private final UsageViewPresentation myPresentation;
|
||||
private final UsageTarget[] mySearchFor;
|
||||
private final Factory<UsageSearcher> mySearcherFactory;
|
||||
private final FindUsagesProcessPresentation myProcessPresentation;
|
||||
private final UsageViewStateListener myListener;
|
||||
|
||||
private SearchForUsagesRunnable(@NotNull Project project,
|
||||
@NotNull AtomicReference<UsageViewImpl> usageViewRef,
|
||||
@NotNull UsageViewPresentation presentation,
|
||||
@NotNull UsageTarget[] searchFor,
|
||||
@NotNull Factory<UsageSearcher> searcherFactory,
|
||||
@NotNull FindUsagesProcessPresentation processPresentation,
|
||||
@Nullable UsageViewStateListener listener) {
|
||||
myProject = project;
|
||||
myUsageViewRef = usageViewRef;
|
||||
myPresentation = presentation;
|
||||
mySearchFor = searchFor;
|
||||
mySearcherFactory = searcherFactory;
|
||||
myProcessPresentation = processPresentation;
|
||||
myListener = listener;
|
||||
}
|
||||
|
||||
private UsageViewImpl getUsageView(ProgressIndicator indicator) {
|
||||
UsageViewImpl usageView = myUsageViewRef.get();
|
||||
if (usageView != null) return usageView;
|
||||
int usageCount = myUsageCountWithoutDefinition.get();
|
||||
if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
|
||||
usageView.associateProgress(indicator);
|
||||
if (myUsageViewRef.compareAndSet(null, usageView)) {
|
||||
openView(usageView);
|
||||
final Usage firstUsage = myFirstUsage.get();
|
||||
if (firstUsage != null) {
|
||||
final UsageViewImpl finalUsageView = usageView;
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finalUsageView.appendUsage(firstUsage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Disposer.dispose(usageView);
|
||||
}
|
||||
return myUsageViewRef.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void openView(@NotNull final UsageViewImpl usageView) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
addContent(usageView, myPresentation);
|
||||
if (myListener != null) {
|
||||
myListener.usageViewCreated(usageView);
|
||||
}
|
||||
showToolWindow(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AtomicBoolean findUsagesStartedShown = new AtomicBoolean();
|
||||
searchUsages(findUsagesStartedShown);
|
||||
endSearchForUsages(findUsagesStartedShown);
|
||||
}
|
||||
|
||||
private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
|
||||
ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
|
||||
TooManyUsagesStatus.createFor(indicator);
|
||||
Alarm findUsagesStartedBalloon = new Alarm();
|
||||
findUsagesStartedBalloon.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, UsageViewManagerImpl.this.myProject,
|
||||
getProgressTitle(myPresentation));
|
||||
findStartedBalloonShown.set(true);
|
||||
}
|
||||
}, 300, ModalityState.NON_MODAL);
|
||||
UsageSearcher usageSearcher = mySearcherFactory.create();
|
||||
|
||||
usageSearcher.generate(new Processor<Usage>() {
|
||||
@Override
|
||||
public boolean process(final Usage usage) {
|
||||
ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
|
||||
if (indicator != null && indicator.isCanceled()) return false;
|
||||
TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator);
|
||||
boolean incrementCounter = !isSelfUsage(usage, mySearchFor);
|
||||
|
||||
if (incrementCounter) {
|
||||
final int usageCount = myUsageCountWithoutDefinition.incrementAndGet();
|
||||
if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
myFirstUsage.compareAndSet(null, usage);
|
||||
}
|
||||
|
||||
final UsageViewImpl usageView = getUsageView(indicator);
|
||||
|
||||
if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsagesStatus.switchTooManyUsagesStatus()) {
|
||||
showTooManyUsagesWarning(myProject, tooManyUsagesStatus, indicator, myPresentation, usageCount, usageView);
|
||||
}
|
||||
|
||||
if (usageView != null) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
usageView.appendUsage(usage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return indicator == null || !indicator.isCanceled();
|
||||
}
|
||||
});
|
||||
if (getUsageView(indicator) != null) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showToolWindow(true);
|
||||
}
|
||||
}, myProject.getDisposed());
|
||||
}
|
||||
Disposer.dispose(findUsagesStartedBalloon);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (findStartedBalloonShown.get()) {
|
||||
Balloon balloon = ToolWindowManager.getInstance(myProject).getToolWindowBalloon(ToolWindowId.FIND);
|
||||
if (balloon != null) {
|
||||
balloon.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, myProject.getDisposed());
|
||||
}
|
||||
|
||||
private void endSearchForUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
|
||||
assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
|
||||
int usageCount = myUsageCountWithoutDefinition.get();
|
||||
if (usageCount == 0 && myProcessPresentation.isShowNotFoundMessage()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
|
||||
final String message = UsageViewBundle.message("dialog.no.usages.found.in",
|
||||
StringUtil.decapitalize(myPresentation.getUsagesString()),
|
||||
myPresentation.getScopeText());
|
||||
|
||||
if (notFoundActions.isEmpty()) {
|
||||
String[] lines = myProcessPresentation.isShowFindOptionsPrompt() ? new String[] {StringUtil.escapeXml(message), createOptionsHtml(mySearchFor)} : new String[]{StringUtil.escapeXml(message)};
|
||||
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
|
||||
MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject, lines);
|
||||
findStartedBalloonShown.set(false);
|
||||
}
|
||||
else {
|
||||
List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
|
||||
titles.add(UsageViewBundle.message("dialog.button.ok"));
|
||||
for (Action action : notFoundActions) {
|
||||
Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
|
||||
if (value == null) value = action.getValue(Action.NAME);
|
||||
|
||||
titles.add((String)value);
|
||||
}
|
||||
|
||||
int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
|
||||
ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
|
||||
|
||||
if (option > 0) {
|
||||
notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
else if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Usage usage = myFirstUsage.get();
|
||||
if (usage.canNavigate()) {
|
||||
usage.navigate(true);
|
||||
flashUsageScriptaculously(usage);
|
||||
}
|
||||
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
|
||||
MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Only one usage found.", createOptionsHtml(
|
||||
mySearchFor));
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
else {
|
||||
final UsageViewImpl usageView = myUsageViewRef.get();
|
||||
if (usageView != null) {
|
||||
usageView.drainQueuedUsageNodes();
|
||||
usageView.setSearchInProgress(false);
|
||||
}
|
||||
if (!myProcessPresentation.getLargeFiles().isEmpty()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyByFindBalloon(null, MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject);
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
}
|
||||
|
||||
if (myListener != null) {
|
||||
myListener.findingUsagesFinished(myUsageViewRef.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void notifyByFindBalloon(final HyperlinkListener listener,
|
||||
@NotNull final MessageType info,
|
||||
@NotNull FindUsagesProcessPresentation processPresentation,
|
||||
@NotNull final Project project,
|
||||
@NotNull String... sLines) {
|
||||
com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered
|
||||
|
||||
final List<String> lines = new ArrayList<String>(Arrays.asList(sLines));
|
||||
final Collection<PsiFile> largeFiles = processPresentation.getLargeFiles();
|
||||
List<String> resultLines = new ArrayList<String>(lines);
|
||||
HyperlinkListener resultListener = listener;
|
||||
if (!largeFiles.isEmpty()) {
|
||||
String shortMessage = "(<a href='" + LARGE_FILES_HREF_TARGET + "'>"
|
||||
+ UsageViewBundle.message("large.files.were.ignored", largeFiles.size()) + "</a>)";
|
||||
|
||||
resultLines.add(shortMessage);
|
||||
resultListener = new HyperlinkAdapter(){
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
if (e.getDescription().equals(LARGE_FILES_HREF_TARGET)) {
|
||||
String detailedMessage = detailedLargeFilesMessage(largeFiles);
|
||||
List<String> strings = new ArrayList<String>(lines);
|
||||
strings.add(detailedMessage);
|
||||
ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
|
||||
}
|
||||
else if (listener != null) {
|
||||
listener.hyperlinkUpdate(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String wrapInHtml(@NotNull List<String> strings) {
|
||||
return XmlStringUtil.wrapInHtml(StringUtil.join(strings, "<br>"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String detailedLargeFilesMessage(@NotNull Collection<PsiFile> largeFiles) {
|
||||
String message = "";
|
||||
if (largeFiles.size() == 1) {
|
||||
final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile();
|
||||
message += "File " + presentableFileInfo(vFile) + " is ";
|
||||
}
|
||||
else {
|
||||
message += "Files<br> ";
|
||||
|
||||
int counter = 0;
|
||||
for (PsiFile file : largeFiles) {
|
||||
final VirtualFile vFile = file.getVirtualFile();
|
||||
message += presentableFileInfo(vFile) + "<br> ";
|
||||
if (counter++ > 10) break;
|
||||
}
|
||||
|
||||
message += "are ";
|
||||
}
|
||||
|
||||
message += "too large and cannot be scanned";
|
||||
return message;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String presentableFileInfo(@NotNull VirtualFile vFile) {
|
||||
return getPresentablePath(vFile)
|
||||
+ " ("
|
||||
+ presentableSize(getFileLength(vFile))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String presentableSize(long bytes) {
|
||||
long megabytes = bytes / (1024 * 1024);
|
||||
return UsageViewBundle.message("find.file.size.megabytes", Long.toString(megabytes));
|
||||
}
|
||||
|
||||
public static long getFileLength(@NotNull final VirtualFile virtualFile) {
|
||||
final long[] length = {-1L};
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@@ -550,52 +256,22 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getPresentablePath(@NotNull final VirtualFile virtualFile) {
|
||||
return "'" + ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return virtualFile.getPresentableUrl();
|
||||
}
|
||||
}) + "'";
|
||||
public static String presentableSize(long bytes) {
|
||||
long megabytes = bytes / (1024 * 1024);
|
||||
return UsageViewBundle.message("find.file.size.megabytes", Long.toString(megabytes));
|
||||
}
|
||||
|
||||
public static boolean isInScope(@NotNull Usage usage, @NotNull SearchScope searchScope) {
|
||||
VirtualFile file = usage instanceof UsageInFile ? ((UsageInFile)usage).getFile() : usage instanceof PsiElementUsage ? PsiUtilCore
|
||||
.getVirtualFile(((PsiElementUsage)usage).getElement()) : null;
|
||||
return file != null && (searchScope instanceof LocalSearchScope
|
||||
? ((LocalSearchScope)searchScope).isInScope(file) : ((GlobalSearchScope)searchScope).contains(file));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private HyperlinkListener createGotToOptionsListener(@NotNull final UsageTarget[] targets) {
|
||||
return new HyperlinkAdapter() {
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
if (e.getDescription().equals(FIND_OPTIONS_HREF_TARGET)) {
|
||||
FindManager.getInstance(myProject).showSettingsAndFindUsages(targets);
|
||||
}
|
||||
}
|
||||
};
|
||||
public static String outOfScopeMessage(int nUsages, @NotNull SearchScope searchScope) {
|
||||
return (nUsages == 1 ? "One usage is" : nUsages + " usages are") +
|
||||
" out of scope '"+ searchScope.getDisplayName()+"'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String createOptionsHtml(@NonNls UsageTarget[] searchFor) {
|
||||
KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(searchFor);
|
||||
String shortcutText = "";
|
||||
if (shortcut != null) {
|
||||
shortcutText = " (" + KeymapUtil.getShortcutText(shortcut) + ")";
|
||||
}
|
||||
return "<a href='" + FIND_OPTIONS_HREF_TARGET + "'>Find Options...</a>" + shortcutText;
|
||||
}
|
||||
|
||||
private static void flashUsageScriptaculously(@NotNull final Usage usage) {
|
||||
if (!(usage instanceof UsageInfo2UsageAdapter)) {
|
||||
return;
|
||||
}
|
||||
UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage;
|
||||
|
||||
Editor editor = usageInfo.openTextEditor(true);
|
||||
if (editor == null) return;
|
||||
TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
|
||||
|
||||
RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6);
|
||||
List<Segment> segments = new ArrayList<Segment>();
|
||||
CommonProcessors.CollectProcessor<Segment> processor = new CommonProcessors.CollectProcessor<Segment>(segments);
|
||||
usageInfo.processRangeMarkers(processor);
|
||||
rangeBlinker.resetMarkers(segments);
|
||||
rangeBlinker.startBlinking();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ public class Patches {
|
||||
public static final boolean USE_REFLECTION_TO_ACCESS_JDK7 = true;
|
||||
|
||||
/**
|
||||
* Marker field to find all usages of workarounds
|
||||
* which will not be needed when migrated to JDK 8+
|
||||
* AtomicIntegerFieldUpdater does not work when SecurityManager is installed
|
||||
* fixed in JDK8
|
||||
*/
|
||||
public static final boolean HACK_USED_WHICH_IS_FIXED_IN_JDK8 = true;
|
||||
public static final boolean JDK_BUG_ID_7103570 = true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,6 +28,8 @@ import java.awt.*;
|
||||
* @author max
|
||||
*/
|
||||
public class EngravedLabel extends JLabel {
|
||||
private Color myShadowColor = EngravedTextGraphics.SHADOW_COLOR;
|
||||
|
||||
public EngravedLabel(String text) {
|
||||
super(text);
|
||||
setOpaque(false);
|
||||
@@ -38,7 +40,18 @@ public class EngravedLabel extends JLabel {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(UIUtil.isUnderDarcula() ? g : new EngravedTextGraphics((Graphics2D)g));
|
||||
protected void paintComponent(Graphics graphics) {
|
||||
if (!UIUtil.isUnderDarcula()) {
|
||||
graphics = new EngravedTextGraphics((Graphics2D)graphics, 0, 1, getShadowColor());
|
||||
}
|
||||
super.paintComponent(graphics);
|
||||
}
|
||||
|
||||
public Color getShadowColor() {
|
||||
return myShadowColor == null ? EngravedTextGraphics.SHADOW_COLOR : myShadowColor;
|
||||
}
|
||||
|
||||
public void setShadowColor(Color shadowColor) {
|
||||
myShadowColor = shadowColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import java.awt.*;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
|
||||
public class EngravedTextGraphics extends Graphics2DDelegate {
|
||||
private static final Color SHADOW_COLOR = Gray._250.withAlpha(140);
|
||||
public static final Color SHADOW_COLOR = Gray._250.withAlpha(140);
|
||||
private static final boolean ALLOW_ENGRAVEMENT = SystemInfo.isMac;
|
||||
private Color myShadowColor;
|
||||
private int myXOffset;
|
||||
|
||||
@@ -58,8 +58,17 @@ class JarLoader extends Loader {
|
||||
}
|
||||
|
||||
void preloadClasses() {
|
||||
ZipFile zipFile;
|
||||
|
||||
try {
|
||||
zipFile = acquireZipFile();
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.debug("url: " + myURL, e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ZipFile zipFile = acquireZipFile();
|
||||
try {
|
||||
JarMemoryLoader loader = JarMemoryLoader.load(zipFile, getBaseURL());
|
||||
if (loader != null) {
|
||||
|
||||
@@ -17,15 +17,18 @@ package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConcurrentMapsTest extends TestCase {
|
||||
public static final TObjectHashingStrategy<String> CUSTOM_STRATEGY = new TObjectHashingStrategy<String>() {
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ConcurrentMapsTest {
|
||||
private static final TObjectHashingStrategy<String> CUSTOM_STRATEGY = new TObjectHashingStrategy<String>() {
|
||||
@Override
|
||||
public int computeHashCode(String object) {
|
||||
return Character.toLowerCase(object.charAt(object.length() - 1));
|
||||
@@ -37,8 +40,9 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testKeysRemovedWhenIdentityStrategyIsUsed() {
|
||||
ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
|
||||
@SuppressWarnings("unchecked") ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
|
||||
map.put(new Object(), new Object());
|
||||
|
||||
tryGcSoftlyReachableObjects(); // sometimes weak references are not collected under linux, try to stress gc to force them
|
||||
@@ -50,6 +54,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertEquals(1, map.underlyingMapSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveFromSoftEntrySet() {
|
||||
ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
|
||||
map.put(this, this);
|
||||
@@ -61,6 +66,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveFromWeakEntrySet() {
|
||||
ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
|
||||
map.put(this, this);
|
||||
@@ -72,6 +78,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTossedWeakKeysAreRemoved() {
|
||||
ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
@@ -87,13 +94,14 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
}
|
||||
|
||||
public static void tryGcSoftlyReachableObjects() {
|
||||
SoftReference reference = new SoftReference(new Object());
|
||||
SoftReference<?> reference = new SoftReference<Object>(new Object());
|
||||
List<Object> list = ContainerUtil.newArrayList();
|
||||
while (reference.get() != null) {
|
||||
list.add(new SoftReference<byte[]>(new byte[(int)Runtime.getRuntime().freeMemory() / 2]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTossedSoftKeysAreRemoved() {
|
||||
ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
@@ -108,6 +116,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertEquals(1, map.underlyingMapSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTossedWeakValueIsRemoved() {
|
||||
ConcurrentWeakValueHashMap<Object, Object> map = new ConcurrentWeakValueHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
@@ -121,6 +130,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
map.put(this, this);
|
||||
assertEquals(1, map.underlyingMapSize());
|
||||
}
|
||||
@Test
|
||||
public void testTossedSoftValueIsRemoved() {
|
||||
ConcurrentSoftValueHashMap<Object, Object> map = new ConcurrentSoftValueHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
@@ -135,6 +145,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertEquals(1, map.underlyingMapSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomStrategy() {
|
||||
SoftHashMap<String, String> map = new SoftHashMap<String, String>(CUSTOM_STRATEGY);
|
||||
|
||||
@@ -145,6 +156,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomStrategyForConcurrentSoft() {
|
||||
ConcurrentSoftHashMap<String, String> map = new ConcurrentSoftHashMap<String, String>(CUSTOM_STRATEGY);
|
||||
|
||||
@@ -156,6 +168,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomStrategyForConcurrentWeakSoft() {
|
||||
ConcurrentWeakKeySoftValueHashMap<String, String> map = new ConcurrentWeakKeySoftValueHashMap<String, String>(1,1,1,CUSTOM_STRATEGY);
|
||||
|
||||
@@ -167,6 +180,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTossedSoftKeyAndValue() {
|
||||
SoftKeySoftValueHashMap<Object, Object> map = new SoftKeySoftValueHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
@@ -179,6 +193,7 @@ public class ConcurrentMapsTest extends TestCase {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTossedWeakKeyAndValue() {
|
||||
WeakKeyWeakValueHashMap<Object, Object> map = new WeakKeyWeakValueHashMap<Object, Object>();
|
||||
map.put(new Object(), new Object());
|
||||
|
||||
@@ -173,14 +173,12 @@ public class LineStatusTracker {
|
||||
@SuppressWarnings({"AutoBoxing"})
|
||||
private RangeHighlighter createHighlighter(final Range range) {
|
||||
LOG.assertTrue(!myReleased, "Already released");
|
||||
int first =
|
||||
range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1());
|
||||
|
||||
int second =
|
||||
range.getOffset2() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset2());
|
||||
TextRange textRange = getCurrentTextRange(range);
|
||||
|
||||
final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true)
|
||||
.addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, null, HighlighterTargetArea.LINES_IN_RANGE);
|
||||
.addRangeHighlighter(textRange.getStartOffset(), textRange.getEndOffset(), HighlighterLayer.FIRST - 1, null,
|
||||
HighlighterTargetArea.LINES_IN_RANGE);
|
||||
final TextAttributes attr = LineStatusTrackerDrawing.getAttributesFor(range);
|
||||
highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor());
|
||||
highlighter.setThinErrorStripeMark(true);
|
||||
@@ -188,14 +186,21 @@ public class LineStatusTracker {
|
||||
highlighter.setGreedyToRight(true);
|
||||
highlighter.setLineMarkerRenderer(LineStatusTrackerDrawing.createRenderer(range, this));
|
||||
highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter());
|
||||
final int line1 = myDocument.getLineNumber(first);
|
||||
final int line2 = myDocument.getLineNumber(second);
|
||||
|
||||
final String tooltip;
|
||||
if (line1 == line2) {
|
||||
tooltip = VcsBundle.message("tooltip.text.line.changed", line1);
|
||||
if (range.getOffset1() == range.getOffset2()) {
|
||||
if (range.getUOffset1() + 1 == range.getUOffset2()) {
|
||||
tooltip = VcsBundle.message("tooltip.text.line.before.deleted", range.getOffset1() + 1);
|
||||
}
|
||||
else {
|
||||
tooltip = VcsBundle.message("tooltip.text.lines.before.deleted", range.getOffset1() + 1, range.getUOffset2() - range.getUOffset1());
|
||||
}
|
||||
}
|
||||
else if (range.getOffset1() + 1 == range.getOffset2()) {
|
||||
tooltip = VcsBundle.message("tooltip.text.line.changed", range.getOffset1() + 1);
|
||||
}
|
||||
else {
|
||||
tooltip = VcsBundle.message("tooltip.text.lines.changed", line1, line2);
|
||||
tooltip = VcsBundle.message("tooltip.text.lines.changed", range.getOffset1() + 1, range.getOffset2());
|
||||
}
|
||||
|
||||
highlighter.setErrorStripeTooltip(tooltip);
|
||||
|
||||
@@ -168,9 +168,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
|
||||
}
|
||||
|
||||
DefaultActionGroup leftToolbar = new DefaultActionGroup();
|
||||
final Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();
|
||||
final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance();
|
||||
if (runner != null && environment != null) {
|
||||
RestartAction restartAction = new RestartAction(executor, runner, myRunContentDescriptor, environment);
|
||||
RestartAction restartAction = new RestartAction(debugExecutor, runner, myRunContentDescriptor, environment);
|
||||
leftToolbar.add(restartAction);
|
||||
restartAction.registerShortcut(myUi.getComponent());
|
||||
|
||||
@@ -221,8 +221,8 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
|
||||
leftToolbar.addSeparator();
|
||||
|
||||
leftToolbar.add(PinToolwindowTabAction.getPinAction());
|
||||
leftToolbar.add(new CloseAction(executor, myRunContentDescriptor, getProject()));
|
||||
leftToolbar.add(new ContextHelpAction(executor.getHelpId()));
|
||||
leftToolbar.add(new CloseAction(environment != null ? environment.getExecutor() : debugExecutor, myRunContentDescriptor, getProject()));
|
||||
leftToolbar.add(new ContextHelpAction(debugExecutor.getHelpId()));
|
||||
|
||||
DefaultActionGroup topToolbar = new DefaultActionGroup();
|
||||
topToolbar.addAll(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP));
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
|
||||
@@ -197,7 +198,14 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
|
||||
|
||||
final Collection<Change> changes = commit.getChanges();
|
||||
if (changes.size() == 1) {
|
||||
return Pair.create(commit, changes.iterator().next().getAfterRevision().getFile());
|
||||
Change change = changes.iterator().next();
|
||||
ContentRevision revision = change.getAfterRevision();
|
||||
if (revision == null) {
|
||||
revision = change.getBeforeRevision();
|
||||
}
|
||||
assert revision != null : "Revision can't be null in " + change;
|
||||
FilePath filePathInRevision = revision.getFile();
|
||||
return Pair.create(commit, filePathInRevision);
|
||||
}
|
||||
for (Change change : changes) {
|
||||
if (change.getAfterRevision() != null && FileUtil.filesEqual(filePath.getIOFile(), change.getAfterRevision().getFile().getIOFile())) {
|
||||
|
||||
@@ -205,7 +205,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
|
||||
boolean notificationShown = false;
|
||||
checkoutOrMerge operation, "feature", [
|
||||
showUntrackedFilesNotification : { String s, Collection c -> notificationShown = true }
|
||||
showUntrackedFilesNotification: { String s, VirtualFile root, Collection c -> notificationShown = true }
|
||||
]
|
||||
|
||||
assertTrue "Untracked files notification was not shown", notificationShown
|
||||
@@ -224,15 +224,15 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
def untracked = ["untracked.txt"]
|
||||
untrackedFileOverwrittenBy(myCommunity, "feature", untracked)
|
||||
|
||||
Collection<VirtualFile> untrackedFiles = null;
|
||||
Collection<String> untrackedPaths = null;
|
||||
checkoutOrMerge operation, "feature", [
|
||||
showUntrackedFilesDialogWithRollback : { String s, String p, Collection files -> untrackedFiles = files; false }
|
||||
showUntrackedFilesDialogWithRollback: {
|
||||
String s, String p, VirtualFile root, Collection<String> files -> untrackedPaths = files; false
|
||||
}
|
||||
]
|
||||
|
||||
assertTrue "Untracked files dialog was not shown", untrackedFiles != null
|
||||
assertEquals "Incorrect set of untracked files was shown in the dialog",
|
||||
untracked,
|
||||
untrackedFiles.collect { FileUtil.getRelativePath(myCommunity.root.path, it.path, '/'.toCharacter()) }
|
||||
assertTrue "Untracked files dialog was not shown", untrackedPaths != null
|
||||
assertEquals "Incorrect set of untracked files was shown in the dialog", untracked.asList(), untrackedPaths.asList()
|
||||
}
|
||||
|
||||
public void "test checkout with local changes overwritten by checkout should show smart checkout dialog"() {
|
||||
@@ -252,7 +252,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
|
||||
List<Change> changes = null;
|
||||
checkoutOrMerge(operation, "feature", [
|
||||
showSmartOperationDialog: { Project p, List<Change> cs, String op, boolean force ->
|
||||
showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean force ->
|
||||
changes = cs
|
||||
DialogWrapper.CANCEL_EXIT_CODE
|
||||
}
|
||||
@@ -349,7 +349,9 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
prepareLocalChangesOverwrittenBy(myUltimate)
|
||||
|
||||
checkoutOrMerge(operation, "feature", [
|
||||
showSmartOperationDialog : { Project p, List<Change> cs, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE },
|
||||
showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean f
|
||||
-> GitSmartOperationDialog.CANCEL_EXIT_CODE
|
||||
},
|
||||
] as GitBranchUiHandler )
|
||||
|
||||
assertNull "Notification was unexpectedly shown:" + myVcsNotifier.lastNotification, myVcsNotifier.lastNotification
|
||||
@@ -372,8 +374,10 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
|
||||
def rollbackMsg = null
|
||||
checkoutOrMerge(operation, "feature", [
|
||||
showSmartOperationDialog : { Project p, List<Change> cs, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE },
|
||||
notifyErrorWithRollbackProposal: { String t, String m, String rp -> rollbackMsg = m ; false }
|
||||
showSmartOperationDialog : {
|
||||
Project p, List<Change> cs, Collection<String> paths, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE
|
||||
},
|
||||
notifyErrorWithRollbackProposal: { String t, String m, String rp -> rollbackMsg = m; false }
|
||||
] as GitBranchUiHandler )
|
||||
|
||||
assertNotNull "Rollback proposal was not shown", rollbackMsg
|
||||
@@ -384,7 +388,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
prepareLocalChangesOverwrittenBy(myUltimate)
|
||||
|
||||
def uiHandler = [
|
||||
showSmartOperationDialog: { Project p, List<Change> cs, String op, boolean force ->
|
||||
showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean force ->
|
||||
GitSmartOperationDialog.FORCE_EXIT_CODE;
|
||||
},
|
||||
] as GitBranchUiHandler
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ public class InconsistentResourceBundleInspection extends GlobalSimpleInspection
|
||||
ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
|
||||
assert visitedBundles != null;
|
||||
if (!visitedBundles.add(resourceBundle)) return;
|
||||
List<PropertiesFile> files = resourceBundle.getPropertiesFiles(manager.getProject());
|
||||
List<PropertiesFile> files = resourceBundle.getPropertiesFiles();
|
||||
if (files.size() < 2) return;
|
||||
BidirectionalMap<PropertiesFile, PropertiesFile> parents = new BidirectionalMap<PropertiesFile, PropertiesFile>();
|
||||
for (PropertiesFile f : files) {
|
||||
|
||||
+11
-1
@@ -4,7 +4,9 @@ properties.files.file.type.description=Properties files
|
||||
remove.property.intention.text=Remove property
|
||||
rename.bundle.enter.new.resource.bundle.base.name.prompt.text=Enter new resource bundle base name
|
||||
rename.bundle.enter.new.resource.bundle.key.name.prompt.text=Enter new resource bundle key name
|
||||
rename.bundle.enter.new.resource.bundle.section.name.prompt.text=Enter new resource bundle section name
|
||||
rename.resource.bundle.dialog.title=Rename Resource Bundle
|
||||
rename.resource.bundle.section.dialog.title=Rename Resource Bundle Section
|
||||
rename.resource.bundle.key.dialog.title=Rename Resource Bundle Key
|
||||
properties.files.inspection.group.display.name=Properties Files
|
||||
unused.property.inspection.display.name=Unused Property
|
||||
@@ -40,4 +42,12 @@ options.properties.attribute.descriptor.property.value=Property value
|
||||
options.properties.attribute.descriptor.key.value.separator=Key/value separator
|
||||
options.properties.attribute.descriptor.comment=Comment
|
||||
options.properties.attribute.descriptor.valid.string.escape=Valid string escape
|
||||
options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape
|
||||
options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape
|
||||
|
||||
new.property.dialog.title=New Property Key
|
||||
new.property.dialog.name.prompt.text=Enter new property key name
|
||||
|
||||
resource.bundle.renamer=Rename resource bundle properties files
|
||||
resource.bundle.renamer.dialog.description=Rename resource bundle properties files with the following names to:
|
||||
resource.bundle.renamer.entity.name=Resource bundle
|
||||
resource.bundle.renamer.option=Rename bound &resource bundle
|
||||
+23
-2
@@ -18,6 +18,7 @@ package com.intellij.lang.properties;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -31,15 +32,29 @@ public class EmptyResourceBundle {
|
||||
private static class Holder {
|
||||
private static final ResourceBundle NULL = new ResourceBundle() {
|
||||
@NotNull
|
||||
public List<PropertiesFile> getPropertiesFiles(final Project project) {
|
||||
@Override
|
||||
public List<PropertiesFile> getPropertiesFiles() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertiesFile getDefaultPropertiesFile(final Project project) {
|
||||
@Override
|
||||
public List<PropertiesFile> getPropertiesFiles(final Project project) {
|
||||
return getPropertiesFiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertiesFile getDefaultPropertiesFile() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertiesFile getDefaultPropertiesFile(final Project project) {
|
||||
return getDefaultPropertiesFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getBaseName() {
|
||||
return "";
|
||||
@@ -49,6 +64,12 @@ public class EmptyResourceBundle {
|
||||
public VirtualFile getBaseDirectory() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
};
|
||||
}
|
||||
public static ResourceBundle getInstance() {
|
||||
|
||||
+22
-10
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -41,8 +42,16 @@ public class PropertiesUtil {
|
||||
private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
|
||||
|
||||
|
||||
public static boolean isPropertyComplete(final Project project, ResourceBundle resourceBundle, String propertyName) {
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles(project);
|
||||
/**
|
||||
* @deprecated use PropertiesUtil.isPropertyComplete(ResourceBundle resourceBundle, String propertyName)
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isPropertyComplete(final Project project, final ResourceBundle resourceBundle, final String propertyName) {
|
||||
return isPropertyComplete(resourceBundle, propertyName);
|
||||
}
|
||||
|
||||
public static boolean isPropertyComplete(final ResourceBundle resourceBundle, final String propertyName) {
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
if (propertiesFile.findPropertyByKey(propertyName) == null) return false;
|
||||
}
|
||||
@@ -50,8 +59,13 @@ public class PropertiesUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getBaseName(@NotNull VirtualFile virtualFile) {
|
||||
String name = virtualFile.getName();
|
||||
public static String getBaseName(@NotNull PsiFile file) {
|
||||
return getBaseName(file.getContainingFile().getVirtualFile());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getBaseName(@NotNull VirtualFile file) {
|
||||
final String name = file.getName();
|
||||
final Matcher matcher = LOCALE_PATTERN.matcher(name);
|
||||
final String baseNameWithExtension;
|
||||
if (matcher.find()) {
|
||||
@@ -92,10 +106,10 @@ public class PropertiesUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getFullName(final PropertiesFile psiFile) {
|
||||
public static String getFullName(final PropertiesFile propertiesFile) {
|
||||
return ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
|
||||
public String compute() {
|
||||
PsiDirectory directory = psiFile.getParent();
|
||||
PsiDirectory directory = propertiesFile.getParent();
|
||||
String packageQualifiedName = getPackageQualifiedName(directory);
|
||||
if (packageQualifiedName == null) {
|
||||
return null;
|
||||
@@ -104,9 +118,7 @@ public class PropertiesUtil {
|
||||
if (qName.length() > 0) {
|
||||
qName.append(".");
|
||||
}
|
||||
final VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
assert virtualFile != null;
|
||||
qName.append(getBaseName(virtualFile));
|
||||
qName.append(getBaseName(propertiesFile.getContainingFile()));
|
||||
return qName.toString();
|
||||
}
|
||||
});
|
||||
@@ -132,7 +144,7 @@ public class PropertiesUtil {
|
||||
@NotNull
|
||||
public static List<IProperty> findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) {
|
||||
List<IProperty> result = new SmartList<IProperty>();
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles(project);
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
result.addAll(propertiesFile.findPropertiesByKey(key));
|
||||
}
|
||||
|
||||
+18
@@ -26,6 +26,7 @@ import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -33,9 +34,23 @@ import java.util.List;
|
||||
public abstract class ResourceBundle {
|
||||
public static final DataKey<ResourceBundle[]> ARRAY_DATA_KEY = DataKey.create("resource.bundle.array");
|
||||
|
||||
@NotNull
|
||||
public abstract List<PropertiesFile> getPropertiesFiles();
|
||||
|
||||
/**
|
||||
* @deprecated, use getPropertiesFiles() instead this method
|
||||
*/
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public abstract List<PropertiesFile> getPropertiesFiles(final Project project);
|
||||
|
||||
@NotNull
|
||||
public abstract PropertiesFile getDefaultPropertiesFile();
|
||||
|
||||
/**
|
||||
* @deprecated, use getDefaultPropertiesFile() instead this method
|
||||
*/
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public abstract PropertiesFile getDefaultPropertiesFile(final Project project);
|
||||
|
||||
@@ -44,4 +59,7 @@ public abstract class ResourceBundle {
|
||||
|
||||
@NotNull
|
||||
public abstract VirtualFile getBaseDirectory();
|
||||
|
||||
@NotNull
|
||||
public abstract Project getProject();
|
||||
}
|
||||
|
||||
+1
-7
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.lang.properties;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -26,11 +25,6 @@ public interface BundleNameEvaluator {
|
||||
|
||||
@Nullable
|
||||
public String evaluateBundleName(final PsiFile psiFile) {
|
||||
final VirtualFile virtualFile = psiFile == null ? null : psiFile.getOriginalFile().getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiDirectory directory = psiFile.getParent();
|
||||
if (directory == null) {
|
||||
return null;
|
||||
@@ -43,7 +37,7 @@ public interface BundleNameEvaluator {
|
||||
if (qName.length() > 0) {
|
||||
qName.append(".");
|
||||
}
|
||||
qName.append(PropertiesUtil.getBaseName(virtualFile));
|
||||
qName.append(PropertiesUtil.getBaseName(psiFile));
|
||||
return qName.toString();
|
||||
}
|
||||
return null;
|
||||
|
||||
+52
-15
@@ -23,44 +23,64 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class PropertiesImplUtil extends PropertiesUtil {
|
||||
public static ResourceBundle getResourceBundle(final PsiFile containingFile) {
|
||||
VirtualFile virtualFile = containingFile.getVirtualFile();
|
||||
if (!containingFile.isValid() || virtualFile == null) {
|
||||
|
||||
@Nullable
|
||||
public static ResourceBundle getResourceBundle(@NotNull final PropertiesFile representative) {
|
||||
final PsiFile containingFile = representative.getContainingFile();
|
||||
if (!containingFile.isValid()) {
|
||||
return EmptyResourceBundle.getInstance();
|
||||
}
|
||||
String baseName = getBaseName(virtualFile);
|
||||
PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
|
||||
final String baseName = getBaseName(containingFile);
|
||||
final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
|
||||
@Nullable
|
||||
public PsiDirectory compute() {
|
||||
return containingFile.getContainingDirectory();
|
||||
}});
|
||||
if (directory == null) return EmptyResourceBundle.getInstance();
|
||||
|
||||
return new ResourceBundleImpl(directory.getVirtualFile(), baseName);
|
||||
return getResourceBundle(baseName, directory);
|
||||
}
|
||||
|
||||
public static boolean isPropertiesFile(VirtualFile file, Project project) {
|
||||
@Nullable
|
||||
private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) {
|
||||
PropertiesFile defaultPropertiesFile = null;
|
||||
for (final PsiFile psiFile : baseDirectory.getFiles()) {
|
||||
if (baseName.equals(getBaseName(psiFile))) {
|
||||
final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
|
||||
if (propertiesFile != null) {
|
||||
if (defaultPropertiesFile == null || defaultPropertiesFile.getName().compareTo(propertiesFile.getName()) < 0) {
|
||||
defaultPropertiesFile = propertiesFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defaultPropertiesFile == null) {
|
||||
return null;
|
||||
}
|
||||
return new ResourceBundleImpl(defaultPropertiesFile);
|
||||
}
|
||||
|
||||
public static boolean isPropertiesFile(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
return getPropertiesFile(PsiManager.getInstance(project).findFile(file)) != null;
|
||||
}
|
||||
|
||||
public static boolean isPropertiesFile(PsiFile file) {
|
||||
public static boolean isPropertiesFile(@Nullable PsiFile file) {
|
||||
return getPropertiesFile(file) != null;
|
||||
}
|
||||
|
||||
@@ -70,8 +90,6 @@ public class PropertiesImplUtil extends PropertiesUtil {
|
||||
return file instanceof PropertiesFile ? (PropertiesFile)file : XmlPropertiesFileImpl.getPropertiesFile(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
public static List<IProperty> findPropertiesByKey(final Project project, final String key) {
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
@@ -94,4 +112,23 @@ public class PropertiesImplUtil extends PropertiesUtil {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResourceBundle createByUrl(final @NotNull String url, final @NotNull Project project) {
|
||||
if (!url.startsWith(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX)) return null;
|
||||
|
||||
final String defaultPropertiesUrl = url.substring(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX.length());
|
||||
final int idx = defaultPropertiesUrl.lastIndexOf('/');
|
||||
if (idx == -1) return null;
|
||||
final String baseDirectoryName = defaultPropertiesUrl.substring(0, idx);
|
||||
final String baseName = defaultPropertiesUrl.substring(idx + 1);
|
||||
final VirtualFile baseDirectoryVirtualFile = VirtualFileManager.getInstance().findFileByUrl(baseDirectoryName);
|
||||
if (baseDirectoryVirtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
final PsiFile baseDirectory = PsiManager.getInstance(project).findFile(baseDirectoryVirtualFile);
|
||||
if (baseDirectory == null || !(baseDirectory instanceof PsiDirectory)) {
|
||||
return null;
|
||||
}
|
||||
return getResourceBundle(baseName, (PsiDirectory)baseDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
+45
-58
@@ -23,36 +23,32 @@ import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ResourceBundleImpl extends ResourceBundle {
|
||||
@NonNls private static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:";
|
||||
@NotNull protected final VirtualFile myBaseDirectory;
|
||||
@NotNull protected final String myBaseName;
|
||||
@NonNls public static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:";
|
||||
@NotNull private final PropertiesFile myDefaultPropertiesFile;
|
||||
|
||||
public ResourceBundleImpl(@NotNull VirtualFile baseDirectory, @NotNull String baseName) {
|
||||
myBaseDirectory = baseDirectory;
|
||||
myBaseName = baseName;
|
||||
public ResourceBundleImpl(@NotNull final PropertiesFile defaultPropertiesFile) {
|
||||
myDefaultPropertiesFile = defaultPropertiesFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PropertiesFile> getPropertiesFiles(final Project project) {
|
||||
VirtualFile[] children = myBaseDirectory.getChildren();
|
||||
@Override
|
||||
public List<PropertiesFile> getPropertiesFiles() {
|
||||
PsiFile[] children = myDefaultPropertiesFile.getParent().getFiles();
|
||||
final String baseName = getBaseName();
|
||||
List<PropertiesFile> result = new SmartList<PropertiesFile>();
|
||||
PsiManager psiManager = PsiManager.getInstance(project);
|
||||
for (VirtualFile file : children) {
|
||||
if (!file.isValid() || file.getExtension() == null) continue;
|
||||
if (Comparing.strEqual(PropertiesUtil.getBaseName(file), myBaseName)) {
|
||||
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(file));
|
||||
for (PsiFile file : children) {
|
||||
if (!file.isValid() || file.getVirtualFile().getExtension() == null) continue;
|
||||
if (Comparing.strEqual(PropertiesUtil.getBaseName(file), baseName)) {
|
||||
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
|
||||
if (propertiesFile != null) {
|
||||
result.add(propertiesFile);
|
||||
}
|
||||
@@ -62,20 +58,38 @@ public class ResourceBundleImpl extends ResourceBundle {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertiesFile getDefaultPropertiesFile(final Project project) {
|
||||
List<PropertiesFile> files = getPropertiesFiles(project);
|
||||
// put default properties file first
|
||||
ContainerUtil.quickSort(files, new Comparator<PropertiesFile>() {
|
||||
public int compare(final PropertiesFile o1, final PropertiesFile o2) {
|
||||
return Comparing.compare(o1.getName(), o2.getName());
|
||||
}
|
||||
});
|
||||
return files.get(0);
|
||||
@Override
|
||||
public List<PropertiesFile> getPropertiesFiles(final Project project) {
|
||||
return getPropertiesFiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertiesFile getDefaultPropertiesFile() {
|
||||
return myDefaultPropertiesFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertiesFile getDefaultPropertiesFile(final Project project) {
|
||||
return getDefaultPropertiesFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getBaseName() {
|
||||
return myBaseName;
|
||||
return PropertiesUtil.getBaseName(myDefaultPropertiesFile.getContainingFile());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getBaseDirectory() {
|
||||
return myDefaultPropertiesFile.getParent().getVirtualFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return myDefaultPropertiesFile.getProject();
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
@@ -83,42 +97,15 @@ public class ResourceBundleImpl extends ResourceBundle {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final ResourceBundleImpl resourceBundle = (ResourceBundleImpl)o;
|
||||
|
||||
if (!myBaseDirectory.equals(resourceBundle.myBaseDirectory)) return false;
|
||||
if (!myBaseName.equals(resourceBundle.myBaseName)) return false;
|
||||
|
||||
if (!myDefaultPropertiesFile.equals(resourceBundle.myDefaultPropertiesFile)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = myBaseDirectory.hashCode();
|
||||
result = 29 * result + myBaseName.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResourceBundle createByUrl(String url) {
|
||||
if (!url.startsWith(RESOURCE_BUNDLE_PREFIX)) return null;
|
||||
|
||||
String defaultPropertiesUrl = url.substring(RESOURCE_BUNDLE_PREFIX.length());
|
||||
final int idx = defaultPropertiesUrl.lastIndexOf('/');
|
||||
if (idx == -1) return null;
|
||||
String baseDir = defaultPropertiesUrl.substring(0, idx);
|
||||
String baseName = defaultPropertiesUrl.substring(idx + 1);
|
||||
VirtualFile baseDirectory = VirtualFileManager.getInstance().findFileByUrl(baseDir);
|
||||
if (baseDirectory != null) {
|
||||
return new ResourceBundleImpl(baseDirectory, baseName);
|
||||
}
|
||||
return null;
|
||||
return myDefaultPropertiesFile.hashCode();
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return RESOURCE_BUNDLE_PREFIX +getBaseDirectory() + "/" + getBaseName();
|
||||
return RESOURCE_BUNDLE_PREFIX + getBaseDirectory() + "/" + getBaseName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getBaseDirectory() {
|
||||
return myBaseDirectory;
|
||||
}
|
||||
|
||||
}
|
||||
+30
-10
@@ -19,31 +19,50 @@
|
||||
*/
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
import com.intellij.ide.presentation.Presentation;
|
||||
import com.intellij.lang.properties.PropertiesImplUtil;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@Presentation(icon = "AllIcons.Nodes.ResourceBundle")
|
||||
public class ResourceBundleAsVirtualFile extends VirtualFile {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
private final VirtualFile myBasePropertiesFile;
|
||||
|
||||
public ResourceBundleAsVirtualFile(@NotNull ResourceBundle resourceBundle) {
|
||||
myResourceBundle = resourceBundle;
|
||||
private ResourceBundleAsVirtualFile(@NotNull final VirtualFile basePropertiesFile) {
|
||||
myBasePropertiesFile = basePropertiesFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return myResourceBundle;
|
||||
public static ResourceBundleAsVirtualFile fromResourceBundle(final @NotNull ResourceBundle resourceBundle) {
|
||||
return new ResourceBundleAsVirtualFile(resourceBundle.getDefaultPropertiesFile().getVirtualFile());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResourceBundle getResourceBundle(final Project project) {
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(myBasePropertiesFile));
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
return PropertiesImplUtil.getResourceBundle(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFileSystem getFileSystem() {
|
||||
return myResourceBundle.getBaseDirectory().getFileSystem();
|
||||
return LocalFileSystem.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,7 +74,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myResourceBundle.getBaseName();
|
||||
return PropertiesUtil.getBaseName(myBasePropertiesFile);
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
@@ -64,17 +83,18 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
|
||||
|
||||
final ResourceBundleAsVirtualFile resourceBundleAsVirtualFile = (ResourceBundleAsVirtualFile)o;
|
||||
|
||||
if (!myResourceBundle.equals(resourceBundleAsVirtualFile.myResourceBundle)) return false;
|
||||
if (!myBasePropertiesFile.equals(resourceBundleAsVirtualFile.myBasePropertiesFile)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myResourceBundle.hashCode();
|
||||
return myBasePropertiesFile.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(Object requestor, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,7 +114,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
|
||||
|
||||
@Override
|
||||
public VirtualFile getParent() {
|
||||
return myResourceBundle.getBaseDirectory();
|
||||
return myBasePropertiesFile.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public interface ResourceBundleEditorViewElement {
|
||||
|
||||
PsiElement[] getPsiElements(@NotNull Project project);
|
||||
|
||||
}
|
||||
+22
-9
@@ -26,6 +26,9 @@ import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -34,36 +37,35 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement {
|
||||
private final Project myProject;
|
||||
public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
|
||||
public ResourceBundleFileStructureViewElement(final Project project, final ResourceBundle resourceBundle) {
|
||||
myProject = project;
|
||||
public ResourceBundleFileStructureViewElement(final ResourceBundle resourceBundle) {
|
||||
myResourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceBundle getValue() {
|
||||
return myResourceBundle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StructureViewTreeElement[] getChildren() {
|
||||
List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(myProject);
|
||||
List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
|
||||
Map<String, IProperty> propertyNames = new LinkedHashMap<String, IProperty>();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
List<IProperty> properties = propertiesFile.getProperties();
|
||||
for (IProperty property : properties) {
|
||||
String name = property.getUnescapedKey();
|
||||
String name = property.getKey();
|
||||
if (!propertyNames.containsKey(name)) {
|
||||
propertyNames.put(name, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>(propertyNames.size());
|
||||
for (String property : propertyNames.keySet()) {
|
||||
//result.add(new PropertiesStructureViewElement(property));
|
||||
result.add(new ResourceBundlePropertyStructureViewElement(myProject, myResourceBundle, property));
|
||||
for (Map.Entry<String, IProperty> propertyEntry : propertyNames.entrySet()) {
|
||||
//result.add(new PropertiesStructureViewElement(propertyEntry));
|
||||
result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, propertyEntry.getValue()));
|
||||
}
|
||||
return result.toArray(new StructureViewTreeElement[result.size()]);
|
||||
}
|
||||
@@ -85,6 +87,17 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement[] getPsiElements(@NotNull Project project) {
|
||||
final List<PropertiesFile> propertiesFiles = getValue().getPropertiesFiles();
|
||||
return ContainerUtil.map2Array(propertiesFiles, new PsiElement[propertiesFiles.size()], new Function<PropertiesFile, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(PropertiesFile propertiesFile) {
|
||||
return propertiesFile.getContainingFile();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void navigate(boolean requestFocus) {
|
||||
|
||||
}
|
||||
|
||||
+19
-10
@@ -20,6 +20,7 @@
|
||||
package com.intellij.lang.properties.editor;
|
||||
|
||||
import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesHighlighter;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
@@ -29,16 +30,16 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement {
|
||||
private final String myPropertyName;
|
||||
private final Project myProject;
|
||||
public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
private final IProperty myProperty;
|
||||
private String myPresentableName;
|
||||
|
||||
private static final TextAttributesKey INCOMPLETE_PROPERTY_KEY;
|
||||
@@ -49,10 +50,19 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
INCOMPLETE_PROPERTY_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_PROPERTY_KEY", textAttributes);
|
||||
|
||||
}
|
||||
public ResourceBundlePropertyStructureViewElement(final Project project, final ResourceBundle resourceBundle, String propertyName) {
|
||||
myProject = project;
|
||||
|
||||
public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final IProperty property) {
|
||||
myResourceBundle = resourceBundle;
|
||||
myPropertyName = propertyName;
|
||||
myProperty = property;
|
||||
}
|
||||
|
||||
public IProperty getProperty() {
|
||||
return myProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement[] getPsiElements(final @NotNull Project project) {
|
||||
return new PsiElement[] {getProperty().getPsiElement()};
|
||||
}
|
||||
|
||||
public void setPresentableName(final String presentableName) {
|
||||
@@ -61,7 +71,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return myPropertyName;
|
||||
return myProperty.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,7 +86,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
return new ColoredItemPresentation() {
|
||||
@Override
|
||||
public String getPresentableText() {
|
||||
return myPresentableName == null ? myPropertyName : myPresentableName;
|
||||
return myPresentableName == null ? myProperty.getName() : myPresentableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +101,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
|
||||
@Override
|
||||
public TextAttributesKey getTextAttributesKey() {
|
||||
boolean isComplete = PropertiesUtil.isPropertyComplete(myProject, myResourceBundle, myPropertyName);
|
||||
boolean isComplete = PropertiesUtil.isPropertyComplete(myResourceBundle, myProperty.getName());
|
||||
|
||||
if (isComplete) {
|
||||
return PropertiesHighlighter.PROPERTY_KEY;
|
||||
@@ -115,5 +125,4 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
|
||||
public boolean canNavigateToSource() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-10
@@ -25,7 +25,6 @@ import com.intellij.ide.util.treeView.smartTree.Sorter;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.structureView.GroupByWordPrefixes;
|
||||
import com.intellij.lang.properties.structureView.PropertiesSeparatorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -33,23 +32,24 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class ResourceBundleStructureViewModel implements PropertiesGroupingStructureViewModel, StructureViewModel.ExpandInfoProvider {
|
||||
private final ResourceBundle myResourceBundle;
|
||||
private final GroupByWordPrefixes myGroupByWordPrefixes;
|
||||
private final GroupByWordPrefixes myByWordPrefixesGrouper;
|
||||
private final StructureViewTreeElement myRoot;
|
||||
|
||||
public ResourceBundleStructureViewModel(final Project project, ResourceBundle root) {
|
||||
public ResourceBundleStructureViewModel(ResourceBundle root) {
|
||||
myResourceBundle = root;
|
||||
String separator = PropertiesSeparatorManager.getInstance().getSeparator(project, new ResourceBundleAsVirtualFile(myResourceBundle));
|
||||
myGroupByWordPrefixes = new GroupByWordPrefixes(separator);
|
||||
myRoot = new ResourceBundleFileStructureViewElement(project, myResourceBundle);
|
||||
String separator = PropertiesSeparatorManager.getInstance(root.getProject()).
|
||||
getSeparator(myResourceBundle);
|
||||
myByWordPrefixesGrouper = new GroupByWordPrefixes(separator);
|
||||
myRoot = new ResourceBundleFileStructureViewElement(myResourceBundle);
|
||||
}
|
||||
|
||||
public void setSeparator(String separator) {
|
||||
myGroupByWordPrefixes.setSeparator(separator);
|
||||
PropertiesSeparatorManager.getInstance().setSeparator(new ResourceBundleAsVirtualFile(myResourceBundle), separator);
|
||||
myByWordPrefixesGrouper.setSeparator(separator);
|
||||
PropertiesSeparatorManager.getInstance(myResourceBundle.getProject()).setSeparator(myResourceBundle, separator);
|
||||
}
|
||||
|
||||
public String getSeparator() {
|
||||
return myGroupByWordPrefixes.getSeparator();
|
||||
return myByWordPrefixesGrouper.getSeparator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -59,7 +59,7 @@ public class ResourceBundleStructureViewModel implements PropertiesGroupingStruc
|
||||
|
||||
@NotNull
|
||||
public Grouper[] getGroupers() {
|
||||
return new Grouper[]{myGroupByWordPrefixes};
|
||||
return new Grouper[]{myByWordPrefixesGrouper};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+3
-3
@@ -54,10 +54,10 @@ public class ResourceBundleUtil {
|
||||
if (virtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
if (virtualFile instanceof ResourceBundleAsVirtualFile) {
|
||||
return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle();
|
||||
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (virtualFile instanceof ResourceBundleAsVirtualFile && project != null) {
|
||||
return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(project);
|
||||
}
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (project != null) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
|
||||
if (psiFile instanceof PropertiesFile) {
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
|
||||
@Override
|
||||
@NotNull
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return PropertiesImplUtil.getResourceBundle(getContainingFile());
|
||||
return PropertiesImplUtil.getResourceBundle(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user