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:
@@ -85,12 +85,12 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementSettingsNode current) {
|
||||
public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatchCondition current) {
|
||||
return SUPPORTED_TYPES.contains(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementSettingsNode current) {
|
||||
public boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatchCondition current) {
|
||||
if (current == null) {
|
||||
return SUPPORTED_MODIFIERS.contains(modifier);
|
||||
}
|
||||
@@ -98,15 +98,15 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
final Ref<Object> typeRef = new Ref<Object>();
|
||||
current.invite(new ArrangementSettingsNodeVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
if (node.getType() == ArrangementSettingType.TYPE) {
|
||||
typeRef.set(node.getValue());
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
if (setting.getType() == ArrangementSettingType.TYPE) {
|
||||
typeRef.set(setting.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
for (ArrangementSettingsNode n : node.getOperands()) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
for (ArrangementMatchCondition n : setting.getOperands()) {
|
||||
if (typeRef.get() != null) {
|
||||
return;
|
||||
}
|
||||
@@ -127,39 +127,39 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node) {
|
||||
final Ref<HierarchicalArrangementSettingsNode> result = new Ref<HierarchicalArrangementSettingsNode>();
|
||||
public HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node) {
|
||||
final Ref<HierarchicalArrangementConditionNode> result = new Ref<HierarchicalArrangementConditionNode>();
|
||||
node.invite(new ArrangementSettingsNodeVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
result.set(new HierarchicalArrangementSettingsNode(node));
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
result.set(new HierarchicalArrangementConditionNode(setting));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
ArrangementSettingsNode typeNode = null;
|
||||
for (ArrangementSettingsNode n : node.getOperands()) {
|
||||
if (n instanceof ArrangementSettingsAtomNode && ((ArrangementSettingsAtomNode)n).getType() == ArrangementSettingType.TYPE) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
ArrangementMatchCondition typeNode = null;
|
||||
for (ArrangementMatchCondition n : setting.getOperands()) {
|
||||
if (n instanceof ArrangementAtomMatchCondition && ((ArrangementAtomMatchCondition)n).getType() == ArrangementSettingType.TYPE) {
|
||||
typeNode = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (typeNode == null) {
|
||||
result.set(new HierarchicalArrangementSettingsNode(node));
|
||||
result.set(new HierarchicalArrangementConditionNode(setting));
|
||||
}
|
||||
else {
|
||||
HierarchicalArrangementSettingsNode parent = new HierarchicalArrangementSettingsNode(typeNode);
|
||||
ArrangementSettingsCompositeNode compositeWithoutType = new ArrangementSettingsCompositeNode(node.getOperator());
|
||||
for (ArrangementSettingsNode n : node.getOperands()) {
|
||||
HierarchicalArrangementConditionNode parent = new HierarchicalArrangementConditionNode(typeNode);
|
||||
ArrangementCompositeMatchCondition compositeWithoutType = new ArrangementCompositeMatchCondition(setting.getOperator());
|
||||
for (ArrangementMatchCondition n : setting.getOperands()) {
|
||||
if (n != typeNode) {
|
||||
compositeWithoutType.addOperand(n);
|
||||
}
|
||||
}
|
||||
if (compositeWithoutType.getOperands().size() == 1) {
|
||||
parent.setChild(new HierarchicalArrangementSettingsNode(compositeWithoutType.getOperands().iterator().next()));
|
||||
parent.setChild(new HierarchicalArrangementConditionNode(compositeWithoutType.getOperands().iterator().next()));
|
||||
}
|
||||
else {
|
||||
parent.setChild(new HierarchicalArrangementSettingsNode(compositeWithoutType));
|
||||
parent.setChild(new HierarchicalArrangementConditionNode(compositeWithoutType));
|
||||
}
|
||||
result.set(parent);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MethodSignatureBackedByPsiMethod extends MethodSignatureBase {
|
||||
super(substitutor, parameterTypes, methodTypeParameters);
|
||||
myIsRaw = isRaw;
|
||||
if (!method.isValid()) {
|
||||
LOG.error("Invalid method: "+method);
|
||||
LOG.error("Invalid method: "+method, new PsiInvalidElementAccessException(method));
|
||||
}
|
||||
myMethod = method;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ public class PsiScopesUtil {
|
||||
@NotNull final PsiElement entrance,
|
||||
@Nullable final PsiElement maxScope,
|
||||
@NotNull final ResolveState state) {
|
||||
LOG.assertTrue(entrance.isValid(), entrance);
|
||||
if (!entrance.isValid()) {
|
||||
LOG.error(new PsiInvalidElementAccessException(entrance));
|
||||
}
|
||||
PsiElement prevParent = entrance;
|
||||
PsiElement scope = entrance;
|
||||
|
||||
|
||||
+6
-7
@@ -18,16 +18,15 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
import com.intellij.psi.codeStyle.arrangement.JavaRearranger;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Before;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -55,11 +54,11 @@ public abstract class AbstractArrangementRuleEditingModelTest {
|
||||
myGrouper = new JavaRearranger();
|
||||
}
|
||||
|
||||
protected void configure(@NotNull ArrangementSettingsNode settingsNode) {
|
||||
myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings);
|
||||
protected void configure(@NotNull ArrangementMatchCondition matchCondition) {
|
||||
myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings);
|
||||
}
|
||||
|
||||
protected static ArrangementSettingsAtomNode atom(@NotNull Object condition) {
|
||||
protected static ArrangementAtomMatchCondition atom(@NotNull Object condition) {
|
||||
final ArrangementSettingType type;
|
||||
if (condition instanceof ArrangementEntryType) {
|
||||
type = ArrangementSettingType.TYPE;
|
||||
@@ -70,7 +69,7 @@ public abstract class AbstractArrangementRuleEditingModelTest {
|
||||
else {
|
||||
throw new IllegalArgumentException(String.format("Unexpected condition of class %s: %s", condition.getClass(), condition));
|
||||
}
|
||||
return new ArrangementSettingsAtomNode(type, condition);
|
||||
return new ArrangementAtomMatchCondition(type, condition);
|
||||
}
|
||||
|
||||
protected void checkRows(int... rows) {
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition
|
||||
import gnu.trove.TIntIntHashMap
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.annotations.Nullable
|
||||
@@ -351,7 +351,7 @@ public class TreeNodeBuilder extends BuilderSupport {
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name) {
|
||||
def result = new ArrangementTreeNode(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, name))
|
||||
def result = new ArrangementTreeNode(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, name))
|
||||
currentNode?.add(result)
|
||||
result
|
||||
}
|
||||
|
||||
+6
-8
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
|
||||
import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and;
|
||||
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.FIELD;
|
||||
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.*;
|
||||
@@ -33,21 +31,21 @@ public class ArrangementRuleEditingModelBuilderTest extends AbstractArrangementR
|
||||
|
||||
@Test
|
||||
public void mapToTheSameLayer() {
|
||||
ArrangementSettingsNode settingsNode = and(atom(PUBLIC), atom(STATIC));
|
||||
myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings);
|
||||
ArrangementMatchCondition matchCondition = and(atom(PUBLIC), atom(STATIC));
|
||||
myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings);
|
||||
checkRows(1);
|
||||
ArrangementRuleEditingModel model = myRowMappings.get(1);
|
||||
assertTrue(model.hasCondition(PUBLIC));
|
||||
assertTrue(model.hasCondition(STATIC));
|
||||
assertFalse(model.hasCondition(PRIVATE));
|
||||
assertEquals(1, myRoot.getChildCount());
|
||||
assertEquals(settingsNode, myRoot.getFirstChild().getBackingSetting());
|
||||
assertEquals(matchCondition, myRoot.getFirstChild().getBackingSetting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitIntoTwoLayers() {
|
||||
ArrangementSettingsNode settingsNode = and(atom(FIELD), atom(PUBLIC), atom(STATIC));
|
||||
myBuilder.build(settingsNode, myTree, myRoot, myGrouper, myRowMappings);
|
||||
ArrangementMatchCondition matchCondition = and(atom(FIELD), atom(PUBLIC), atom(STATIC));
|
||||
myBuilder.build(matchCondition, myTree, myRoot, myGrouper, myRowMappings);
|
||||
|
||||
checkRows(2);
|
||||
|
||||
|
||||
+12
-12
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and;
|
||||
@@ -39,9 +39,9 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
|
||||
ArrangementTreeNode child = myRoot.getFirstChild();
|
||||
assertNotNull(child);
|
||||
ArrangementSettingsNode expectedSettingsNode = and(atom(PUBLIC), atom(STATIC));
|
||||
assertEquals(expectedSettingsNode, child.getBackingSetting());
|
||||
assertEquals(expectedSettingsNode, model.getSettingsNode());
|
||||
ArrangementMatchCondition expectedMatchCondition = and(atom(PUBLIC), atom(STATIC));
|
||||
assertEquals(expectedMatchCondition, child.getBackingSetting());
|
||||
assertEquals(expectedMatchCondition, model.getMatchCondition());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,7 +54,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
model.addAndCondition(atom(FIELD));
|
||||
|
||||
assertEquals(2, model.getRow());
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC)), model.getSettingsNode());
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC)), model.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode fieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(fieldNode);
|
||||
@@ -76,7 +76,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
|
||||
assertEquals(1, myRowMappings.size());
|
||||
assertSame(model, myRowMappings.get(2));
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC), atom(STATIC)), model.getSettingsNode());
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC), atom(STATIC)), model.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode fieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(fieldNode);
|
||||
@@ -98,7 +98,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
|
||||
assertEquals(1, myRowMappings.size());
|
||||
assertSame(model, myRowMappings.get(2));
|
||||
assertEquals(and(atom(FIELD), atom(STATIC)), model.getSettingsNode());
|
||||
assertEquals(and(atom(FIELD), atom(STATIC)), model.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode fieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(fieldNode);
|
||||
@@ -119,7 +119,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
model.removeAndCondition(atom(PUBLIC));
|
||||
|
||||
assertEquals(1, model.getRow());
|
||||
assertEquals(atom(FIELD), model.getSettingsNode());
|
||||
assertEquals(atom(FIELD), model.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode fieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(fieldNode);
|
||||
@@ -143,10 +143,10 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
modelToChange.removeAndCondition(atom(PUBLIC));
|
||||
|
||||
assertSame(1, modelToChange.getRow());
|
||||
assertEquals(atom(FIELD), modelToChange.getSettingsNode());
|
||||
assertEquals(atom(FIELD), modelToChange.getMatchCondition());
|
||||
|
||||
assertSame(3, siblingModel.getRow());
|
||||
assertEquals(and(atom(FIELD), atom(STATIC)), siblingModel.getSettingsNode());
|
||||
assertEquals(and(atom(FIELD), atom(STATIC)), siblingModel.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode atomFieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(atomFieldNode);
|
||||
@@ -177,10 +177,10 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
|
||||
assertEquals(2, myRowMappings.size());
|
||||
assertSame(siblingModel, myRowMappings.get(2));
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC)), siblingModel.getSettingsNode());
|
||||
assertEquals(and(atom(FIELD), atom(PUBLIC)), siblingModel.getMatchCondition());
|
||||
|
||||
assertSame(modelToChange, myRowMappings.get(3));
|
||||
assertEquals(atom(FIELD), modelToChange.getSettingsNode());
|
||||
assertEquals(atom(FIELD), modelToChange.getMatchCondition());
|
||||
|
||||
ArrangementTreeNode compositeFieldNode = myRoot.getFirstChild();
|
||||
assertNotNull(compositeFieldNode);
|
||||
|
||||
@@ -125,6 +125,7 @@ public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText
|
||||
getEmptyText().setText(UIBundle.message("no.patterns"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myTable.getEmptyText();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jps.model.library;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.JpsElement;
|
||||
import org.jetbrains.jps.model.JpsNamedElement;
|
||||
import org.jetbrains.jps.model.JpsReferenceableElement;
|
||||
@@ -32,6 +33,10 @@ public interface JpsLibrary extends JpsNamedElement, JpsReferenceableElement<Jps
|
||||
@NotNull
|
||||
JpsLibraryType<?> getType();
|
||||
|
||||
@Nullable
|
||||
<P extends JpsElement>
|
||||
JpsTypedLibrary<P> asTyped(@NotNull JpsLibraryType<P> type);
|
||||
|
||||
@NotNull
|
||||
JpsElement getProperties();
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ public interface JpsLibraryCollection {
|
||||
@NotNull
|
||||
List<JpsLibrary> getLibraries();
|
||||
|
||||
@NotNull
|
||||
<P extends JpsElement>
|
||||
Iterable<JpsTypedLibrary<P>> getLibraries(@NotNull JpsLibraryType<P> type);
|
||||
|
||||
void addLibrary(@NotNull JpsLibrary library);
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -12,21 +12,15 @@ import java.util.List;
|
||||
public abstract class JpsNamedElementReferenceBase<S extends JpsNamedElement, T extends JpsNamedElement, Self extends JpsNamedElementReferenceBase<S, T, Self>>
|
||||
extends JpsCompositeElementBase<Self> implements JpsElementReference<T> {
|
||||
private static final JpsElementChildRole<JpsElementReference<? extends JpsCompositeElement>> PARENT_REFERENCE_ROLE = JpsElementChildRoleBase.create("parent");
|
||||
protected final JpsElementCollectionRole<? extends S> myCollectionRole;
|
||||
protected final String myElementName;
|
||||
|
||||
protected JpsNamedElementReferenceBase(@NotNull JpsElementCollectionRole<? extends S> role,
|
||||
@NotNull String elementName,
|
||||
@NotNull JpsElementReference<? extends JpsCompositeElement> parentReference) {
|
||||
super();
|
||||
myCollectionRole = role;
|
||||
protected JpsNamedElementReferenceBase(@NotNull String elementName, @NotNull JpsElementReference<? extends JpsCompositeElement> parentReference) {
|
||||
myElementName = elementName;
|
||||
myContainer.setChild(PARENT_REFERENCE_ROLE, parentReference);
|
||||
}
|
||||
|
||||
protected JpsNamedElementReferenceBase(JpsNamedElementReferenceBase<S, T, Self> original) {
|
||||
super(original);
|
||||
myCollectionRole = original.myCollectionRole;
|
||||
myElementName = original.myElementName;
|
||||
}
|
||||
|
||||
@@ -35,7 +29,7 @@ public abstract class JpsNamedElementReferenceBase<S extends JpsNamedElement, T
|
||||
final JpsCompositeElement parent = getParentReference().resolve();
|
||||
if (parent == null) return null;
|
||||
|
||||
JpsElementCollectionImpl<? extends S> collection = parent.getContainer().getChild(myCollectionRole);
|
||||
JpsElementCollectionImpl<? extends S> collection = getCollection(parent);
|
||||
if (collection == null) return null;
|
||||
|
||||
final List<? extends S> elements = collection.getElements();
|
||||
@@ -50,10 +44,19 @@ public abstract class JpsNamedElementReferenceBase<S extends JpsNamedElement, T
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract JpsElementCollectionImpl<? extends S> getCollection(@NotNull JpsCompositeElement parent);
|
||||
|
||||
@Nullable
|
||||
protected abstract T resolve(S element);
|
||||
|
||||
public JpsElementReference<? extends JpsCompositeElement> getParentReference() {
|
||||
return myContainer.getChild(PARENT_REFERENCE_ROLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpsElementReference<T> asExternal(@NotNull JpsModel model) {
|
||||
model.registerExternalReference(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jps.model.impl;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.JpsCompositeElement;
|
||||
import org.jetbrains.jps.model.JpsElementReference;
|
||||
import org.jetbrains.jps.model.JpsNamedElement;
|
||||
@@ -9,17 +10,26 @@ import org.jetbrains.jps.model.JpsNamedElement;
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class JpsNamedElementReferenceImpl<T extends JpsNamedElement, Self extends JpsNamedElementReferenceImpl<T, Self>> extends JpsNamedElementReferenceBase<T, T, Self> {
|
||||
protected final JpsElementCollectionRole<? extends T> myCollectionRole;
|
||||
|
||||
protected JpsNamedElementReferenceImpl(@NotNull JpsElementCollectionRole<? extends T> role, @NotNull String elementName,
|
||||
@NotNull JpsElementReference<? extends JpsCompositeElement> parentReference) {
|
||||
super(role, elementName, parentReference);
|
||||
super(elementName, parentReference);
|
||||
myCollectionRole = role;
|
||||
}
|
||||
|
||||
protected JpsNamedElementReferenceImpl(JpsNamedElementReferenceImpl<T, Self> original) {
|
||||
super(original);
|
||||
myCollectionRole = original.myCollectionRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T resolve(T element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JpsElementCollectionImpl<? extends T> getCollection(@NotNull JpsCompositeElement parent) {
|
||||
return parent.getContainer().getChild(myCollectionRole);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -2,8 +2,8 @@ package org.jetbrains.jps.model.library.impl;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.JpsElement;
|
||||
import org.jetbrains.jps.model.JpsElementCollection;
|
||||
import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
|
||||
import org.jetbrains.jps.model.impl.JpsElementCollectionImpl;
|
||||
import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.library.JpsLibraryCollection;
|
||||
import org.jetbrains.jps.model.library.JpsLibraryType;
|
||||
@@ -15,9 +15,9 @@ import java.util.List;
|
||||
* @author nik
|
||||
*/
|
||||
public class JpsLibraryCollectionImpl implements JpsLibraryCollection {
|
||||
private final JpsElementCollection<JpsLibrary> myCollection;
|
||||
private final JpsElementCollectionImpl<JpsLibrary> myCollection;
|
||||
|
||||
public JpsLibraryCollectionImpl(JpsElementCollection<JpsLibrary> collection) {
|
||||
public JpsLibraryCollectionImpl(JpsElementCollectionImpl<JpsLibrary> collection) {
|
||||
myCollection = collection;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,12 @@ public class JpsLibraryCollectionImpl implements JpsLibraryCollection {
|
||||
return myCollection.getElements();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <P extends JpsElement> Iterable<JpsTypedLibrary<P>> getLibraries(@NotNull JpsLibraryType<P> type) {
|
||||
return myCollection.getElementsOfType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLibrary(@NotNull JpsLibrary library) {
|
||||
myCollection.addChild(library);
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jps.model.library.impl;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.JpsPathUtil;
|
||||
import org.jetbrains.jps.model.*;
|
||||
import org.jetbrains.jps.model.impl.JpsElementCollectionImpl;
|
||||
@@ -37,6 +38,13 @@ public class JpsLibraryImpl<P extends JpsElement> extends JpsNamedCompositeEleme
|
||||
return myLibraryType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <P extends JpsElement> JpsTypedLibrary<P> asTyped(@NotNull JpsLibraryType<P> type) {
|
||||
//noinspection unchecked
|
||||
return myLibraryType.equals(type) ? (JpsTypedLibrary<P>)this : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public P getProperties() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.jetbrains.jps.model.library.impl;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.JpsCompositeElement;
|
||||
import org.jetbrains.jps.model.JpsElement;
|
||||
import org.jetbrains.jps.model.JpsElementReference;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.impl.JpsElementCollectionImpl;
|
||||
import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase;
|
||||
import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.library.JpsTypedLibrary;
|
||||
@@ -18,10 +19,9 @@ import org.jetbrains.jps.model.library.sdk.JpsSdkType;
|
||||
public class JpsSdkReferenceImpl<P extends JpsElement> extends JpsNamedElementReferenceBase<JpsLibrary, JpsTypedLibrary<JpsSdk<P>>, JpsSdkReferenceImpl<P>> implements JpsSdkReference<P> {
|
||||
private final JpsSdkType<P> mySdkType;
|
||||
|
||||
public JpsSdkReferenceImpl(@NotNull String elementName,
|
||||
@NotNull JpsSdkType<P> sdkType,
|
||||
public JpsSdkReferenceImpl(@NotNull String elementName, @NotNull JpsSdkType<P> sdkType,
|
||||
@NotNull JpsElementReference<? extends JpsCompositeElement> parentReference) {
|
||||
super(JpsLibraryRole.LIBRARIES_COLLECTION_ROLE, elementName, parentReference);
|
||||
super(elementName, parentReference);
|
||||
mySdkType = sdkType;
|
||||
}
|
||||
|
||||
@@ -37,11 +37,7 @@ public class JpsSdkReferenceImpl<P extends JpsElement> extends JpsNamedElementRe
|
||||
|
||||
@Override
|
||||
protected JpsTypedLibrary<JpsSdk<P>> resolve(JpsLibrary element) {
|
||||
if (element.getType().equals(mySdkType)) {
|
||||
//noinspection unchecked
|
||||
return (JpsTypedLibrary<JpsSdk<P>>)element;
|
||||
}
|
||||
return null;
|
||||
return element.asTyped(mySdkType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -50,9 +46,8 @@ public class JpsSdkReferenceImpl<P extends JpsElement> extends JpsNamedElementRe
|
||||
return new JpsSdkReferenceImpl<P>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpsSdkReferenceImpl<P> asExternal(@NotNull JpsModel model) {
|
||||
model.registerExternalReference(this);
|
||||
return this;
|
||||
@Nullable
|
||||
protected JpsElementCollectionImpl<? extends JpsLibrary> getCollection(@NotNull JpsCompositeElement parent) {
|
||||
return parent.getContainer().getChild(JpsLibraryRole.LIBRARIES_COLLECTION_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.jetbrains.jps.model.module.impl;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.JpsElementReference;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.impl.JpsNamedElementReferenceImpl;
|
||||
import org.jetbrains.jps.model.module.JpsFacet;
|
||||
import org.jetbrains.jps.model.module.JpsFacetReference;
|
||||
@@ -25,10 +23,4 @@ public class JpsFacetReferenceImpl extends JpsNamedElementReferenceImpl<JpsFacet
|
||||
public JpsFacetReferenceImpl createCopy() {
|
||||
return new JpsFacetReferenceImpl(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpsElementReference<JpsFacet> asExternal(@NotNull JpsModel model) {
|
||||
model.registerExternalReference(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,34 +16,56 @@
|
||||
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
public class PsiInvalidElementAccessException extends RuntimeException {
|
||||
private final SoftReference<PsiElement> myElementReference; // to prevent leaks, exceptions are stored in IdeaLogger
|
||||
private final SoftReference<PsiElement> myElementReference; // to prevent leaks, since exceptions are stored in IdeaLogger
|
||||
|
||||
public PsiInvalidElementAccessException(PsiElement element) {
|
||||
super(element != null ? "Element: " + element.getClass() : "Unknown psi element");
|
||||
myElementReference = new SoftReference<PsiElement>(element);
|
||||
this(element, null, null);
|
||||
}
|
||||
|
||||
public PsiInvalidElementAccessException(PsiElement element, String message) {
|
||||
super(message);
|
||||
myElementReference = new SoftReference<PsiElement>(element);
|
||||
this(element, message, null);
|
||||
}
|
||||
|
||||
public PsiInvalidElementAccessException(PsiElement element, Throwable cause) {
|
||||
super(cause);
|
||||
myElementReference = new SoftReference<PsiElement>(element);
|
||||
this(element, null, cause);
|
||||
}
|
||||
|
||||
public PsiInvalidElementAccessException(PsiElement element, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
super((element != null ? "Element: " + element.getClass() + " because: " + reason(element) : "Unknown psi element") +
|
||||
(message == null ? "" : "; " + message), cause);
|
||||
myElementReference = new SoftReference<PsiElement>(element);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
private static String reason(@NotNull PsiElement element){
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (file == null) return element.getParent() == null ? "parent is null" : "containing file is null";
|
||||
FileViewProvider provider = file.getViewProvider();
|
||||
VirtualFile vFile = provider.getVirtualFile();
|
||||
if (!vFile.isValid()) return vFile+" is invalid";
|
||||
if (!provider.isPhysical()) return "non-physical provider"; // "dummy" file
|
||||
PsiManager manager = file.getManager();
|
||||
if (manager.getProject().isDisposed()) return "project is disposed";
|
||||
Language language = file.getLanguage();
|
||||
if (language != provider.getBaseLanguage()) return "File language:"+language+" != Provider base language:"+provider.getBaseLanguage();
|
||||
|
||||
FileViewProvider provider1 = manager.findViewProvider(vFile);
|
||||
if (provider != provider1) return "different providers: "+provider+"("+Integer.toHexString(System.identityHashCode(provider))+"); "+provider1+"("+Integer.toHexString(System.identityHashCode(provider1))+")";
|
||||
return "psi is outdated";
|
||||
}
|
||||
|
||||
public PsiElement getPsiElement() {
|
||||
return myElementReference.get();
|
||||
}
|
||||
|
||||
@@ -171,19 +171,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
final VirtualFile vFile = getViewProvider().getVirtualFile();
|
||||
FileViewProvider provider = getViewProvider();
|
||||
final VirtualFile vFile = provider.getVirtualFile();
|
||||
if (!vFile.isValid()) return false;
|
||||
if (!getViewProvider().isPhysical()) return true; // "dummy" file
|
||||
if (!provider.isPhysical()) return true; // "dummy" file
|
||||
if (myManager.getProject().isDisposed()) return false;
|
||||
return isPsiUpToDate(vFile);
|
||||
|
||||
//FileViewProvider viewProvider = getViewProvider();
|
||||
//if (!viewProvider.isPhysical()) return true; // "dummy" file
|
||||
//final VirtualFile vFile = viewProvider.getVirtualFile();
|
||||
//if (!vFile.isValid() || !isPsiUpToDate(vFile)) return false;
|
||||
//PsiManager manager = getManager();
|
||||
//boolean valid = manager != null && !manager.getProject().isDisposed();
|
||||
//return valid;
|
||||
}
|
||||
|
||||
protected boolean isPsiUpToDate(@NotNull VirtualFile vFile) {
|
||||
|
||||
@@ -23,12 +23,14 @@ import com.intellij.execution.configurations.RunProfile;
|
||||
import com.intellij.execution.process.ProcessNotCreatedException;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -95,7 +97,8 @@ public class ExecutionUtil {
|
||||
@Override
|
||||
public void run() {
|
||||
ToolWindowManager.getInstance(project).notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener);
|
||||
ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, null).notify(project);
|
||||
NotificationListener notificationListener = ObjectUtils.tryCast(finalListener, NotificationListener.class);
|
||||
ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, notificationListener).notify(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,15 +16,13 @@
|
||||
package com.intellij.psi.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.CompositeArrangementEntryMatcher;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNodeVisitor;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.*;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -116,18 +114,18 @@ public class ArrangementUtil {
|
||||
//region Rule composition
|
||||
|
||||
@NotNull
|
||||
public static ArrangementSettingsNode and(@NotNull ArrangementSettingsNode... nodes) {
|
||||
final ArrangementSettingsCompositeNode result = new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND);
|
||||
public static ArrangementMatchCondition and(@NotNull ArrangementMatchCondition... nodes) {
|
||||
final ArrangementCompositeMatchCondition result = new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND);
|
||||
final ArrangementSettingsNodeVisitor visitor = new ArrangementSettingsNodeVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition node) {
|
||||
result.addOperand(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
if (node.getOperator() == ArrangementSettingsCompositeNode.Operator.AND) {
|
||||
for (ArrangementSettingsNode operand : node.getOperands()) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition node) {
|
||||
if (node.getOperator() == ArrangementCompositeMatchCondition.Operator.AND) {
|
||||
for (ArrangementMatchCondition operand : node.getOperands()) {
|
||||
operand.invite(this);
|
||||
}
|
||||
}
|
||||
@@ -136,7 +134,7 @@ public class ArrangementUtil {
|
||||
}
|
||||
}
|
||||
};
|
||||
for (ArrangementSettingsNode node : nodes) {
|
||||
for (ArrangementMatchCondition node : nodes) {
|
||||
node.invite(visitor);
|
||||
}
|
||||
return result;
|
||||
|
||||
+11
-9
@@ -18,19 +18,21 @@ package com.intellij.psi.codeStyle.arrangement.model;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
* Encapsulates a single atom match condition, e.g. 'entry type is field' or 'entry has 'static' modifier' etc.
|
||||
* <p/>
|
||||
* Not thread-safe..
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/8/12 1:17 PM
|
||||
*/
|
||||
public class ArrangementSettingsAtomNode implements ArrangementSettingsNode {
|
||||
public class ArrangementAtomMatchCondition implements ArrangementMatchCondition {
|
||||
|
||||
@NotNull private final ArrangementSettingType myType;
|
||||
@NotNull private final Object myValue;
|
||||
|
||||
private boolean myInverted;
|
||||
|
||||
public ArrangementSettingsAtomNode(@NotNull ArrangementSettingType type, @NotNull Object value) {
|
||||
public ArrangementAtomMatchCondition(@NotNull ArrangementSettingType type, @NotNull Object value) {
|
||||
myType = type;
|
||||
myValue = value;
|
||||
}
|
||||
@@ -75,15 +77,15 @@ public class ArrangementSettingsAtomNode implements ArrangementSettingsNode {
|
||||
return false;
|
||||
}
|
||||
|
||||
ArrangementSettingsAtomNode node = (ArrangementSettingsAtomNode)o;
|
||||
ArrangementAtomMatchCondition setting = (ArrangementAtomMatchCondition)o;
|
||||
|
||||
if (myInverted != node.myInverted) {
|
||||
if (myInverted != setting.myInverted) {
|
||||
return false;
|
||||
}
|
||||
if (myType != node.myType) {
|
||||
if (myType != setting.myType) {
|
||||
return false;
|
||||
}
|
||||
if (!myValue.equals(node.myValue)) {
|
||||
if (!myValue.equals(setting.myValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,8 +94,8 @@ public class ArrangementSettingsAtomNode implements ArrangementSettingsNode {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsAtomNode clone() {
|
||||
ArrangementSettingsAtomNode result = new ArrangementSettingsAtomNode(myType, myValue);
|
||||
public ArrangementAtomMatchCondition clone() {
|
||||
ArrangementAtomMatchCondition result = new ArrangementAtomMatchCondition(myType, myValue);
|
||||
result.setInverted(myInverted);
|
||||
return result;
|
||||
}
|
||||
+15
-13
@@ -22,26 +22,28 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
* Encapsulates composite match condition, e.g. "an entry has type 'field' and modifier 'static'".
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/8/12 1:18 PM
|
||||
*/
|
||||
public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode {
|
||||
public class ArrangementCompositeMatchCondition implements ArrangementMatchCondition {
|
||||
|
||||
@NotNull private final Set<ArrangementSettingsNode> myOperands = new HashSet<ArrangementSettingsNode>();
|
||||
@NotNull private final Set<ArrangementMatchCondition> myOperands = new HashSet<ArrangementMatchCondition>();
|
||||
@NotNull private final Operator myOperator;
|
||||
|
||||
public ArrangementSettingsCompositeNode(@NotNull Operator operator) {
|
||||
public ArrangementCompositeMatchCondition(@NotNull Operator operator) {
|
||||
myOperator = operator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<ArrangementSettingsNode> getOperands() {
|
||||
public Set<ArrangementMatchCondition> getOperands() {
|
||||
return myOperands;
|
||||
}
|
||||
|
||||
public ArrangementSettingsCompositeNode addOperand(@NotNull ArrangementSettingsNode node) {
|
||||
public ArrangementCompositeMatchCondition addOperand(@NotNull ArrangementMatchCondition node) {
|
||||
myOperands.add(node);
|
||||
return this;
|
||||
}
|
||||
@@ -55,12 +57,12 @@ public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode
|
||||
public void invite(@NotNull ArrangementSettingsNodeVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsCompositeNode clone() {
|
||||
ArrangementSettingsCompositeNode result = new ArrangementSettingsCompositeNode(myOperator);
|
||||
for (ArrangementSettingsNode operand : myOperands) {
|
||||
public ArrangementCompositeMatchCondition clone() {
|
||||
ArrangementCompositeMatchCondition result = new ArrangementCompositeMatchCondition(myOperator);
|
||||
for (ArrangementMatchCondition operand : myOperands) {
|
||||
result.addOperand(operand.clone());
|
||||
}
|
||||
return result;
|
||||
@@ -82,12 +84,12 @@ public class ArrangementSettingsCompositeNode implements ArrangementSettingsNode
|
||||
return false;
|
||||
}
|
||||
|
||||
ArrangementSettingsCompositeNode node = (ArrangementSettingsCompositeNode)o;
|
||||
ArrangementCompositeMatchCondition setting = (ArrangementCompositeMatchCondition)o;
|
||||
|
||||
if (!myOperands.equals(node.myOperands)) {
|
||||
if (!myOperands.equals(setting.myOperands)) {
|
||||
return false;
|
||||
}
|
||||
if (myOperator != node.myOperator) {
|
||||
if (myOperator != setting.myOperator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+6
-3
@@ -15,18 +15,21 @@
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement.model;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
* Generic data model for {@link ArrangementEntryMatcher arrangement entry matcher}.
|
||||
* <p/>
|
||||
* Implementations of this interface are not obliged to be thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/8/12 11:13 AM
|
||||
*/
|
||||
public interface ArrangementSettingsNode extends Cloneable {
|
||||
public interface ArrangementMatchCondition extends Cloneable {
|
||||
|
||||
void invite(@NotNull ArrangementSettingsNodeVisitor visitor);
|
||||
|
||||
@NotNull
|
||||
ArrangementSettingsNode clone();
|
||||
ArrangementMatchCondition clone();
|
||||
}
|
||||
+2
-2
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public interface ArrangementSettingsNodeVisitor {
|
||||
|
||||
void visit(@NotNull ArrangementSettingsAtomNode node);
|
||||
void visit(@NotNull ArrangementAtomMatchCondition setting);
|
||||
|
||||
void visit(@NotNull ArrangementSettingsCompositeNode node);
|
||||
void visit(@NotNull ArrangementCompositeMatchCondition setting);
|
||||
}
|
||||
|
||||
+9
-9
@@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* {@link #getCurrent() Wraps} {@link ArrangementSettingsNode} in order to allow to build {@link #getChild() hierarchy}
|
||||
* {@link #getCurrent() Wraps} {@link ArrangementMatchCondition} in order to allow to build {@link #getChild() hierarchy}
|
||||
* from a plain sequence of them
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
@@ -27,29 +27,29 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/8/12 1:23 PM
|
||||
*/
|
||||
public class HierarchicalArrangementSettingsNode {
|
||||
public class HierarchicalArrangementConditionNode {
|
||||
|
||||
@NotNull private final ArrangementSettingsNode myCurrent;
|
||||
@Nullable private HierarchicalArrangementSettingsNode myChild;
|
||||
@NotNull private final ArrangementMatchCondition myCurrent;
|
||||
@Nullable private HierarchicalArrangementConditionNode myChild;
|
||||
|
||||
public HierarchicalArrangementSettingsNode(@NotNull ArrangementSettingsNode current) {
|
||||
public HierarchicalArrangementConditionNode(@NotNull ArrangementMatchCondition current) {
|
||||
myCurrent = current;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ArrangementSettingsNode getCurrent() {
|
||||
public ArrangementMatchCondition getCurrent() {
|
||||
return myCurrent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HierarchicalArrangementSettingsNode getChild() {
|
||||
public HierarchicalArrangementConditionNode getChild() {
|
||||
return myChild;
|
||||
}
|
||||
|
||||
public void setChild(@Nullable HierarchicalArrangementSettingsNode child) {
|
||||
public void setChild(@Nullable HierarchicalArrangementConditionNode child) {
|
||||
myChild = child;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myCurrent.toString();
|
||||
+21
-22
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNodeVisitor;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.*;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -27,7 +26,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Encapsulates information about {@link ArrangementSettingsNode standard arrangement match rule settings}.
|
||||
* Encapsulates information about {@link ArrangementMatchCondition standard arrangement match rule settings}.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
@@ -36,23 +35,23 @@ import java.util.Set;
|
||||
*/
|
||||
public class ArrangementMatcherSettings implements Cloneable {
|
||||
|
||||
@NotNull private final List<ArrangementSettingsNode> myConditions = new ArrayList<ArrangementSettingsNode>();
|
||||
@NotNull private final Set<Object> myValues = new HashSet<Object>();
|
||||
@NotNull private final ArrangementSettingsNodeVisitor myAddVisitor = new MyAddVisitor();
|
||||
@NotNull private final ArrangementSettingsNodeVisitor myRemoveVisitor = new MyRemoveVisitor();
|
||||
@NotNull private final List<ArrangementMatchCondition> myConditions = new ArrayList<ArrangementMatchCondition>();
|
||||
@NotNull private final Set<Object> myValues = new HashSet<Object>();
|
||||
@NotNull private final ArrangementSettingsNodeVisitor myAddVisitor = new MyAddVisitor();
|
||||
@NotNull private final ArrangementSettingsNodeVisitor myRemoveVisitor = new MyRemoveVisitor();
|
||||
|
||||
@NotNull
|
||||
public List<ArrangementSettingsNode> getConditions() {
|
||||
public List<ArrangementMatchCondition> getConditions() {
|
||||
return myConditions;
|
||||
}
|
||||
|
||||
public boolean addCondition(@NotNull ArrangementSettingsNode condition) {
|
||||
public boolean addCondition(@NotNull ArrangementMatchCondition condition) {
|
||||
int size = myConditions.size();
|
||||
condition.invite(myAddVisitor);
|
||||
return myConditions.size() > size;
|
||||
}
|
||||
|
||||
public boolean removeCondition(@NotNull ArrangementSettingsNode condition) {
|
||||
public boolean removeCondition(@NotNull ArrangementMatchCondition condition) {
|
||||
int size = myConditions.size();
|
||||
condition.invite(myRemoveVisitor);
|
||||
return myConditions.size() < size;
|
||||
@@ -72,14 +71,14 @@ public class ArrangementMatcherSettings implements Cloneable {
|
||||
|
||||
private class MyAddVisitor implements ArrangementSettingsNodeVisitor {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
myConditions.add(node);
|
||||
myValues.add(node.getValue());
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
myConditions.add(setting);
|
||||
myValues.add(setting.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
for (ArrangementSettingsNode n : node.getOperands()) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
for (ArrangementMatchCondition n : setting.getOperands()) {
|
||||
n.invite(this);
|
||||
}
|
||||
}
|
||||
@@ -87,14 +86,14 @@ public class ArrangementMatcherSettings implements Cloneable {
|
||||
|
||||
private class MyRemoveVisitor implements ArrangementSettingsNodeVisitor {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
myConditions.remove(node);
|
||||
myValues.remove(node.getValue());
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
myConditions.remove(setting);
|
||||
myValues.remove(setting.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
for (ArrangementSettingsNode n : node.getOperands()) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
for (ArrangementMatchCondition n : setting.getOperands()) {
|
||||
n.invite(this);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -39,12 +39,12 @@ public interface ArrangementSettingsGrouper {
|
||||
* |
|
||||
* ---public---static---final
|
||||
* </pre>
|
||||
* That means that we'll return a {@link HierarchicalArrangementSettingsNode} with condition <code>'type: field'</code> and
|
||||
* That means that we'll return a {@link HierarchicalArrangementConditionNode} with condition <code>'type: field'</code> and
|
||||
* a single child node with composite <code>'AND'</code> condition <code>'modifier: public; modifier: static; modifier: final'</code>.
|
||||
*
|
||||
* @param node settings node which conditions should be grouped
|
||||
* @return grouping-aware node
|
||||
*/
|
||||
@NotNull
|
||||
HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node);
|
||||
HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node);
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,7 +41,7 @@ public interface ArrangementStandardSettingsAware {
|
||||
* (<code>null</code> to indicate a query if given entry type is supported in general)
|
||||
* @return <code>true</code> if given entry type is supported; <code>false</code> otherwise
|
||||
*/
|
||||
boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementSettingsNode current);
|
||||
boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatchCondition current);
|
||||
|
||||
/**
|
||||
* Allows to answer if given modifier can be applied for the rule specified by the given settings node.
|
||||
@@ -51,7 +51,7 @@ public interface ArrangementStandardSettingsAware {
|
||||
* (<code>null</code> to indicate a query if given modifier is supported in general)
|
||||
* @return <code>true</code> if given modifier is supported; <code>false</code> otherwise
|
||||
*/
|
||||
boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementSettingsNode current);
|
||||
boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatchCondition current);
|
||||
|
||||
/**
|
||||
* @return collections of mutual exclusion settings. E.g. not more than one visibility modifier can be used for a single
|
||||
|
||||
+4
-4
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -29,8 +29,8 @@ public class DefaultArrangementSettingsGrouper implements ArrangementSettingsGro
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HierarchicalArrangementSettingsNode group(@NotNull ArrangementSettingsNode node) {
|
||||
public HierarchicalArrangementConditionNode group(@NotNull ArrangementMatchCondition node) {
|
||||
// Don't group.
|
||||
return new HierarchicalArrangementSettingsNode(node);
|
||||
return new HierarchicalArrangementConditionNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
+42
-17
@@ -16,9 +16,9 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
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.model.ArrangementSettingsNodeVisitor;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -26,13 +26,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link ArrangementNodeComponent Component} for showing {@link ArrangementSettingsCompositeNode composite nodes}.
|
||||
* {@link ArrangementNodeComponent Component} for showing {@link ArrangementCompositeMatchCondition composite nodes}.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
@@ -45,35 +46,35 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
|
||||
|
||||
@NotNull private final List<ArrangementNodeComponent> myComponents = new ArrayList<ArrangementNodeComponent>();
|
||||
|
||||
@NotNull private final ArrangementSettingsCompositeNode mySettingsNode;
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
@NotNull private final ArrangementCompositeMatchCondition mySetting;
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
|
||||
public ArrangementAndNodeComponent(@NotNull ArrangementSettingsCompositeNode node,
|
||||
public ArrangementAndNodeComponent(@NotNull ArrangementCompositeMatchCondition setting,
|
||||
@NotNull ArrangementNodeComponentFactory factory,
|
||||
@NotNull ArrangementNodeDisplayManager manager)
|
||||
{
|
||||
mySettingsNode = node;
|
||||
mySetting = setting;
|
||||
setLayout(null);
|
||||
int x = 0;
|
||||
final Map<Object, ArrangementSettingsNode> operands = new HashMap<Object, ArrangementSettingsNode>();
|
||||
final Map<Object, ArrangementMatchCondition> operands = new HashMap<Object, ArrangementMatchCondition>();
|
||||
ArrangementSettingsNodeVisitor visitor = new ArrangementSettingsNodeVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition node) {
|
||||
operands.put(node.getValue(), node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
operands.put(node, node);
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition node) {
|
||||
operands.put(node, node);
|
||||
}
|
||||
};
|
||||
for (ArrangementSettingsNode operand : node.getOperands()) {
|
||||
for (ArrangementMatchCondition operand : setting.getOperands()) {
|
||||
operand.invite(visitor);
|
||||
}
|
||||
|
||||
|
||||
List<Object> ordered = manager.sort(operands.keySet());
|
||||
for (Object key : ordered) {
|
||||
ArrangementSettingsNode operand = operands.get(key);
|
||||
ArrangementMatchCondition operand = operands.get(key);
|
||||
assert operand != null;
|
||||
ArrangementNodeComponent component = factory.getComponent(operand);
|
||||
myComponents.add(component);
|
||||
@@ -87,8 +88,8 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsNode getSettingsNode() {
|
||||
return mySettingsNode;
|
||||
public ArrangementMatchCondition getMatchCondition() {
|
||||
return mySetting;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -194,6 +195,30 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle handleMouseMove(@NotNull MouseEvent event) {
|
||||
Point location = event.getLocationOnScreen();
|
||||
for (ArrangementNodeComponent component : myComponents) {
|
||||
Rectangle bounds = component.getScreenBounds();
|
||||
if (bounds != null && bounds.contains(location)) {
|
||||
return component.handleMouseMove(event);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseClick(@NotNull MouseEvent event) {
|
||||
Point location = event.getLocationOnScreen();
|
||||
for (ArrangementNodeComponent component : myComponents) {
|
||||
Rectangle bounds = component.getScreenBounds();
|
||||
if (bounds != null && bounds.contains(location)) {
|
||||
component.handleMouseClick(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s)", StringUtil.join(myComponents, " and "));
|
||||
|
||||
+92
-10
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -25,9 +27,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
* {@link ArrangementNodeComponent} for {@link ArrangementAtomMatchCondition} representation.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/8/12 10:06 AM
|
||||
@@ -68,7 +73,9 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull private final ArrangementSettingsAtomNode mySettingsNode;
|
||||
@NotNull private final ArrangementAtomMatchCondition myCondition;
|
||||
@Nullable private final ActionButton myCloseButton;
|
||||
@Nullable private final Consumer<ArrangementAtomMatchCondition> myCloseCallback;
|
||||
|
||||
@Nullable private Dimension mySize;
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
@@ -76,18 +83,61 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
private boolean myEnabled = true;
|
||||
private boolean mySelected;
|
||||
private boolean myInverted;
|
||||
private boolean myCloseButtonHovered;
|
||||
|
||||
public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager, @NotNull ArrangementSettingsAtomNode node) {
|
||||
mySettingsNode = node;
|
||||
public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager,
|
||||
@NotNull ArrangementAtomMatchCondition condition,
|
||||
@Nullable Consumer<ArrangementAtomMatchCondition> closeCallback)
|
||||
{
|
||||
myCondition = condition;
|
||||
myCloseCallback = closeCallback;
|
||||
myLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
myLabel.setText(manager.getDisplayValue(node));
|
||||
mySize = new Dimension(manager.getMaxWidth(node.getType()), myLabel.getPreferredSize().height);
|
||||
myLabel.setText(manager.getDisplayValue(condition));
|
||||
|
||||
int width = manager.getMaxWidth(condition.getType());
|
||||
int height = myLabel.getPreferredSize().height;
|
||||
final ArrangementRemoveConditionAction action;
|
||||
if (closeCallback == null) {
|
||||
myCloseButton = null;
|
||||
action = null;
|
||||
}
|
||||
else {
|
||||
action = new ArrangementRemoveConditionAction();
|
||||
|
||||
Icon buttonIcon = action.getTemplatePresentation().getIcon();
|
||||
Dimension buttonSize = new Dimension(buttonIcon.getIconWidth(), buttonIcon.getIconHeight());
|
||||
myCloseButton = new ActionButton(action, action.getTemplatePresentation().clone(), ArrangementConstants.RULE_TREE_PLACE, buttonSize) {
|
||||
@Override
|
||||
protected Icon getIcon() {
|
||||
return myCloseButtonHovered ? action.getTemplatePresentation().getHoveredIcon() : action.getTemplatePresentation().getIcon();
|
||||
}
|
||||
};
|
||||
Dimension preferredButtonSize = myCloseButton.getPreferredSize();
|
||||
width += preferredButtonSize.width;
|
||||
height = Math.max(height, preferredButtonSize.height);
|
||||
}
|
||||
|
||||
mySize = new Dimension(width, height);
|
||||
|
||||
GridBagConstraints constraints = new GridBag().anchor(GridBagConstraints.CENTER).insets(0, 0, 0, 0);
|
||||
|
||||
JPanel labelPanel = new JPanel(new GridBagLayout());
|
||||
JPanel labelPanel = new JPanel(new GridBagLayout()) {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Rectangle buttonBounds = getCloseButtonScreenLocation();
|
||||
if (buttonBounds != null && action != null) {
|
||||
Point mouseScreenLocation = MouseInfo.getPointerInfo().getLocation();
|
||||
myCloseButtonHovered = buttonBounds.contains(mouseScreenLocation);
|
||||
}
|
||||
super.paint(g);
|
||||
}
|
||||
};
|
||||
myLabel.setBackground(Color.red);
|
||||
labelPanel.add(myLabel, constraints);
|
||||
if (myCloseButton != null) {
|
||||
labelPanel.add(myCloseButton, new GridBag().anchor(GridBagConstraints.EAST).insets(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
labelPanel.setBorder(IdeBorderFactory.createEmptyBorder(PADDING));
|
||||
labelPanel.setOpaque(false);
|
||||
|
||||
@@ -113,8 +163,8 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsAtomNode getSettingsNode() {
|
||||
return mySettingsNode;
|
||||
public ArrangementAtomMatchCondition getMatchCondition() {
|
||||
return myCondition;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -168,6 +218,38 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
myInverted = inverted;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Rectangle handleMouseMove(@NotNull MouseEvent event) {
|
||||
Rectangle buttonBounds = getCloseButtonScreenLocation();
|
||||
if (buttonBounds == null) {
|
||||
return null;
|
||||
}
|
||||
boolean mouseOverButton = buttonBounds.contains(event.getLocationOnScreen());
|
||||
return (mouseOverButton ^ myCloseButtonHovered) ? buttonBounds : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseClick(@NotNull MouseEvent event) {
|
||||
Rectangle buttonBounds = getCloseButtonScreenLocation();
|
||||
if (buttonBounds != null && buttonBounds.contains(event.getLocationOnScreen()) && myCloseCallback != null) {
|
||||
myCloseCallback.consume(myCondition);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Rectangle getCloseButtonScreenLocation() {
|
||||
if (myCloseButton == null || myScreenBounds == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle buttonBounds = myCloseButton.getBounds();
|
||||
buttonBounds = SwingUtilities.convertRectangle(myCloseButton.getParent(), buttonBounds, myRenderer);
|
||||
buttonBounds.x += myScreenBounds.x;
|
||||
buttonBounds.y += myScreenBounds.y;
|
||||
return buttonBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myLabel.getText();
|
||||
|
||||
+22
-22
@@ -18,9 +18,9 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementMatcherSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import com.intellij.util.containers.Stack;
|
||||
@@ -58,7 +58,7 @@ public class ArrangementConfigUtil {
|
||||
*/
|
||||
@NotNull
|
||||
public static Map<ArrangementSettingType, Collection<?>> buildAvailableOptions(@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementSettingsNode settings)
|
||||
@Nullable ArrangementMatchCondition settings)
|
||||
{
|
||||
Map<ArrangementSettingType, Collection<?>> result = new EnumMap<ArrangementSettingType, Collection<?>>(ArrangementSettingType.class);
|
||||
processData(filter, settings, result, ArrangementSettingType.TYPE, ArrangementEntryType.values());
|
||||
@@ -67,7 +67,7 @@ public class ArrangementConfigUtil {
|
||||
}
|
||||
|
||||
private static <T> void processData(@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementSettingsNode settings,
|
||||
@Nullable ArrangementMatchCondition settings,
|
||||
@NotNull Map<ArrangementSettingType, Collection<?>> result,
|
||||
@NotNull ArrangementSettingType type,
|
||||
@NotNull T[] values)
|
||||
@@ -89,7 +89,7 @@ public class ArrangementConfigUtil {
|
||||
|
||||
public static boolean isEnabled(@NotNull Object conditionId,
|
||||
@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementSettingsNode settings)
|
||||
@Nullable ArrangementMatchCondition settings)
|
||||
{
|
||||
if (conditionId instanceof ArrangementEntryType) {
|
||||
return filter.isEnabled((ArrangementEntryType)conditionId, settings);
|
||||
@@ -121,15 +121,15 @@ public class ArrangementConfigUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getDepth(@NotNull HierarchicalArrangementSettingsNode node) {
|
||||
HierarchicalArrangementSettingsNode child = node.getChild();
|
||||
public static int getDepth(@NotNull HierarchicalArrangementConditionNode node) {
|
||||
HierarchicalArrangementConditionNode child = node.getChild();
|
||||
return child == null ? 1 : 1 + getDepth(child);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HierarchicalArrangementSettingsNode getLast(@NotNull HierarchicalArrangementSettingsNode node) {
|
||||
HierarchicalArrangementSettingsNode result = node;
|
||||
for (HierarchicalArrangementSettingsNode child = node.getChild(); child != null; child = child.getChild()) {
|
||||
public static HierarchicalArrangementConditionNode getLast(@NotNull HierarchicalArrangementConditionNode node) {
|
||||
HierarchicalArrangementConditionNode result = node;
|
||||
for (HierarchicalArrangementConditionNode child = node.getChild(); child != null; child = child.getChild()) {
|
||||
result = child;
|
||||
}
|
||||
return result;
|
||||
@@ -175,25 +175,25 @@ public class ArrangementConfigUtil {
|
||||
/**
|
||||
* @param uiParentNode UI tree node which should hold UI nodes created for representing given settings node;
|
||||
* <code>null</code> as an indication that we want to create a standalone nodes hierarchy
|
||||
* @param settingsNode settings node which should be represented at the UI tree denoted by the given UI tree node
|
||||
* @param conditionNode settings node which should be represented at the UI tree denoted by the given UI tree node
|
||||
* @param model tree model to use for the tree modification
|
||||
* @return pair {@code (bottom-most leaf node created; number of rows created)}
|
||||
*/
|
||||
@NotNull
|
||||
public static Pair<ArrangementTreeNode, Integer> map(@Nullable ArrangementTreeNode uiParentNode,
|
||||
@NotNull HierarchicalArrangementSettingsNode settingsNode,
|
||||
@NotNull HierarchicalArrangementConditionNode conditionNode,
|
||||
@Nullable DefaultTreeModel model)
|
||||
{
|
||||
ArrangementTreeNode uiNode = null;
|
||||
int rowsCreated = 0;
|
||||
if (uiParentNode != null && uiParentNode.getChildCount() > 0) {
|
||||
ArrangementTreeNode child = uiParentNode.getChildAt(uiParentNode.getChildCount() - 1);
|
||||
if (settingsNode.getCurrent().equals(child.getBackingSetting())) {
|
||||
if (conditionNode.getCurrent().equals(child.getBackingSetting())) {
|
||||
uiNode = child;
|
||||
}
|
||||
}
|
||||
if (uiNode == null) {
|
||||
uiNode = new ArrangementTreeNode(settingsNode.getCurrent());
|
||||
uiNode = new ArrangementTreeNode(conditionNode.getCurrent());
|
||||
if (uiParentNode != null) {
|
||||
if (model == null) {
|
||||
uiParentNode.add(uiNode);
|
||||
@@ -205,9 +205,9 @@ public class ArrangementConfigUtil {
|
||||
rowsCreated++;
|
||||
}
|
||||
ArrangementTreeNode leaf = uiNode;
|
||||
HierarchicalArrangementSettingsNode childSettingsNode = settingsNode.getChild();
|
||||
if (childSettingsNode != null) {
|
||||
Pair<ArrangementTreeNode, Integer> pair = map(uiNode, childSettingsNode, model);
|
||||
HierarchicalArrangementConditionNode childConditionNode = conditionNode.getChild();
|
||||
if (childConditionNode != null) {
|
||||
Pair<ArrangementTreeNode, Integer> pair = map(uiNode, childConditionNode, model);
|
||||
leaf = pair.first;
|
||||
rowsCreated += pair.second;
|
||||
}
|
||||
@@ -527,13 +527,13 @@ public class ArrangementConfigUtil {
|
||||
}
|
||||
|
||||
private static boolean hasEqualSetting(@NotNull ArrangementTreeNode node1, @NotNull ArrangementTreeNode node2) {
|
||||
ArrangementSettingsNode setting1 = node1.getBackingSetting();
|
||||
ArrangementSettingsNode setting2 = node2.getBackingSetting();
|
||||
if (setting1 == null) {
|
||||
return setting2 == null;
|
||||
ArrangementMatchCondition matchCondition1 = node1.getBackingSetting();
|
||||
ArrangementMatchCondition matchCondition2 = node2.getBackingSetting();
|
||||
if (matchCondition1 == null) {
|
||||
return matchCondition2 == null;
|
||||
}
|
||||
else {
|
||||
return setting1.equals(setting2);
|
||||
return matchCondition1.equals(matchCondition2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ public class ArrangementConstants {
|
||||
|
||||
@NonNls public static final String ACTION_GROUP_RULE_EDITOR_CONTEXT_MENU = "Arrangement.RuleEditor.Context.Menu";
|
||||
@NonNls public static final String RULE_EDITOR_PLACE = "Arrangement.RuleEditor.Place";
|
||||
@NonNls public static final String RULE_TREE_PLACE = "Arrangement.RuleTree.Place";
|
||||
|
||||
private ArrangementConstants() {
|
||||
}
|
||||
|
||||
+9
-9
@@ -16,8 +16,8 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import com.intellij.util.ui.MultiRowFlowPanel;
|
||||
@@ -80,7 +80,7 @@ public class ArrangementMatcherRuleEditor extends JPanel {
|
||||
|
||||
JPanel valuesPanel = new MultiRowFlowPanel(FlowLayout.LEFT, 8, 5);
|
||||
for (Object value : manager.sort(values)) {
|
||||
ArrangementAtomNodeComponent component = new ArrangementAtomNodeComponent(manager, new ArrangementSettingsAtomNode(key, value));
|
||||
ArrangementAtomNodeComponent component = new ArrangementAtomNodeComponent(manager, new ArrangementAtomMatchCondition(key, value), null);
|
||||
myComponents.put(value, component);
|
||||
valuesPanel.add(component.getUiComponent());
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class ArrangementMatcherRuleEditor extends JPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<ArrangementSettingType, Collection<?>> available = ArrangementConfigUtil.buildAvailableOptions(myFilter, model.getSettingsNode());
|
||||
Map<ArrangementSettingType, Collection<?>> available = ArrangementConfigUtil.buildAvailableOptions(myFilter, model.getMatchCondition());
|
||||
for (Collection<?> ids : available.values()) {
|
||||
for (Object id : ids) {
|
||||
ArrangementAtomNodeComponent component = myComponents.get(id);
|
||||
@@ -138,30 +138,30 @@ public class ArrangementMatcherRuleEditor extends JPanel {
|
||||
if (component == null) {
|
||||
return;
|
||||
}
|
||||
ArrangementSettingsAtomNode settingsNode = component.getSettingsNode();
|
||||
boolean remove = myModel.hasCondition(settingsNode.getValue());
|
||||
ArrangementAtomMatchCondition setting = component.getMatchCondition();
|
||||
boolean remove = myModel.hasCondition(setting.getValue());
|
||||
component.setSelected(!remove);
|
||||
repaintComponent(component);
|
||||
if (remove) {
|
||||
myModel.removeAndCondition(settingsNode);
|
||||
myModel.removeAndCondition(setting);
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<Set<?>> mutexes = myFilter.getMutexes();
|
||||
for (Set<?> mutex : mutexes) {
|
||||
if (!mutex.contains(settingsNode.getValue())) {
|
||||
if (!mutex.contains(setting.getValue())) {
|
||||
continue;
|
||||
}
|
||||
for (Object key : mutex) {
|
||||
if (myModel.hasCondition(key)) {
|
||||
ArrangementAtomNodeComponent componentToDeselect = myComponents.get(key);
|
||||
componentToDeselect.setSelected(false);
|
||||
myModel.removeAndCondition(componentToDeselect.getSettingsNode());
|
||||
myModel.removeAndCondition(componentToDeselect.getMatchCondition());
|
||||
repaintComponent(componentToDeselect);
|
||||
}
|
||||
}
|
||||
}
|
||||
myModel.addAndCondition(settingsNode);
|
||||
myModel.addAndCondition(setting);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+18
-2
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
@@ -32,7 +33,7 @@ import java.awt.*;
|
||||
public interface ArrangementNodeComponent {
|
||||
|
||||
@NotNull
|
||||
ArrangementSettingsNode getSettingsNode();
|
||||
ArrangementMatchCondition getMatchCondition();
|
||||
|
||||
// TODO den add doc
|
||||
@NotNull
|
||||
@@ -54,4 +55,19 @@ public interface ArrangementNodeComponent {
|
||||
* @param selected flag that indicates if current component should be drawn as 'selected'
|
||||
*/
|
||||
void setSelected(boolean selected);
|
||||
|
||||
/**
|
||||
* Instructs current component about mose move event.
|
||||
* <p/>
|
||||
* Primary intention is to allow to react on event like 'on mouse hover' etc. We can't do that by subscribing to the
|
||||
* mouse events at the {@link #getUiComponent() corresponding UI control} because it's used only as a renderer and is not put
|
||||
* to the containers hierarchy, hence, doesn't receive mouse events.
|
||||
*
|
||||
* @param event target mouse move event
|
||||
* @return bounds to be repainted (in screen coordinates) if any; <code>null</code> otherwise
|
||||
*/
|
||||
@Nullable
|
||||
Rectangle handleMouseMove(@NotNull MouseEvent event);
|
||||
|
||||
void handleMouseClick(@NotNull MouseEvent event);
|
||||
}
|
||||
|
||||
+14
-8
@@ -17,6 +17,7 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.*;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -25,25 +26,30 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class ArrangementNodeComponentFactory {
|
||||
|
||||
@NotNull private final ArrangementNodeDisplayManager myDisplayManager;
|
||||
@NotNull private final ArrangementNodeDisplayManager myDisplayManager;
|
||||
private Consumer<ArrangementAtomMatchCondition> myRemoveConditionCallback;
|
||||
|
||||
public ArrangementNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager) {
|
||||
public ArrangementNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager,
|
||||
@NotNull Consumer<ArrangementAtomMatchCondition> removeConditionCallback)
|
||||
{
|
||||
myDisplayManager = manager;
|
||||
myRemoveConditionCallback = removeConditionCallback;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ArrangementNodeComponent getComponent(@NotNull ArrangementSettingsNode node) {
|
||||
public ArrangementNodeComponent getComponent(@NotNull ArrangementMatchCondition node) {
|
||||
final Ref<ArrangementNodeComponent> ref = new Ref<ArrangementNodeComponent>();
|
||||
node.invite(new ArrangementSettingsNodeVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
ref.set(new ArrangementAtomNodeComponent(myDisplayManager, node));
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
ref.set(new ArrangementAtomNodeComponent(myDisplayManager, setting, myRemoveConditionCallback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
switch (node.getOperator()) {
|
||||
case AND: ref.set(new ArrangementAndNodeComponent(node, ArrangementNodeComponentFactory.this, myDisplayManager)); break;
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
switch (setting.getOperator()) {
|
||||
case AND:
|
||||
ref.set(new ArrangementAndNodeComponent(setting, ArrangementNodeComponentFactory.this, myDisplayManager)); break;
|
||||
case OR: // TODO den implement
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -18,8 +18,8 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
@@ -67,8 +67,8 @@ public class ArrangementNodeDisplayManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDisplayValue(@NotNull ArrangementSettingsAtomNode node) {
|
||||
return getDisplayValue(node.getValue());
|
||||
public String getDisplayValue(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
return getDisplayValue(setting.getValue());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/23/12 11:41 AM
|
||||
*/
|
||||
public class ArrangementRemoveConditionAction extends AnAction {
|
||||
|
||||
private static final Icon ICON = AllIcons.Actions.CloseNew;
|
||||
private static final Icon HOVER_ICON = AllIcons.Actions.CloseNewHovered;
|
||||
|
||||
public ArrangementRemoveConditionAction() {
|
||||
getTemplatePresentation().setIcon(ICON);
|
||||
getTemplatePresentation().setHoveredIcon(HOVER_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
// TODO den implement
|
||||
System.out.println("ArrangementRemoveConditionAction.actionPerformed()");
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -17,15 +17,13 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.tree.TreeNode;
|
||||
|
||||
/**
|
||||
* Combines and encapsulates information about arrangement matcher rules representation (tree nodes) and
|
||||
* underlying {@link ArrangementSettingsNode data model}.
|
||||
* underlying {@link ArrangementMatchCondition data model}.
|
||||
* <p/>
|
||||
* Implementations of this interface are not obliged to be thread-safe.
|
||||
*
|
||||
@@ -35,7 +33,7 @@ import javax.swing.tree.TreeNode;
|
||||
public interface ArrangementRuleEditingModel {
|
||||
|
||||
@NotNull
|
||||
ArrangementSettingsNode getSettingsNode();
|
||||
ArrangementMatchCondition getMatchCondition();
|
||||
|
||||
/**
|
||||
* Allows to answer if current model has a registered condition for the given key. A key is expected to be one of the standard
|
||||
@@ -47,7 +45,7 @@ public interface ArrangementRuleEditingModel {
|
||||
*/
|
||||
boolean hasCondition(@NotNull Object key);
|
||||
|
||||
void addAndCondition(@NotNull ArrangementSettingsAtomNode node);
|
||||
void addAndCondition(@NotNull ArrangementAtomMatchCondition condition);
|
||||
|
||||
void removeAndCondition(@NotNull ArrangementSettingsNode node);
|
||||
void removeAndCondition(@NotNull ArrangementMatchCondition condition);
|
||||
}
|
||||
|
||||
+10
-10
@@ -17,8 +17,8 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementConditionNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementSettingsGrouper;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
@@ -31,7 +31,7 @@ import javax.swing.tree.TreeNode;
|
||||
|
||||
/**
|
||||
* Holds glue logic between arrangement settings and their representation -
|
||||
* '{@link ArrangementSettingsNode} -> {@link ArrangementRuleEditingModel}'
|
||||
* '{@link ArrangementMatchCondition} -> {@link ArrangementRuleEditingModel}'
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*
|
||||
@@ -45,11 +45,11 @@ public class ArrangementRuleEditingModelBuilder {
|
||||
* <pre>
|
||||
* <ol>
|
||||
* <li>
|
||||
* {@link HierarchicalArrangementSettingsNode Groups} given {@link ArrangementSettingsNode settings} using
|
||||
* the given {@link ArrangementSettingsGrouper#group(ArrangementSettingsNode) strategy};
|
||||
* {@link HierarchicalArrangementConditionNode Groups} given {@link ArrangementMatchCondition settings} using
|
||||
* the given {@link ArrangementSettingsGrouper#group(ArrangementMatchCondition) strategy};
|
||||
* </li>
|
||||
* <li>
|
||||
* Build {@link DefaultMutableTreeNode tree nodes} for the {@link HierarchicalArrangementSettingsNode groiping-aware nodes}
|
||||
* Build {@link DefaultMutableTreeNode tree nodes} for the {@link HierarchicalArrangementConditionNode groiping-aware nodes}
|
||||
* and register them within the target tree structure (denoted by the given settings root element);
|
||||
* </li>
|
||||
* <li>
|
||||
@@ -58,7 +58,7 @@ public class ArrangementRuleEditingModelBuilder {
|
||||
* </ol>
|
||||
* </pre>
|
||||
*
|
||||
* @param setting target settings to process
|
||||
* @param matchCondition target settings to process
|
||||
* @param tree UI tree which shows arrangement matcher rules
|
||||
* @param root UI tree settings root to use (may be not the same as the tree root)
|
||||
* @param grouper strategy that knows how to
|
||||
@@ -67,7 +67,7 @@ public class ArrangementRuleEditingModelBuilder {
|
||||
* @param rowMappings container to hold built {@link ArrangementRuleEditingModel editing models} (UI tree row numbers are used as keys)
|
||||
*/
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void build(@NotNull ArrangementSettingsNode setting,
|
||||
public void build(@NotNull ArrangementMatchCondition matchCondition,
|
||||
@NotNull JTree tree,
|
||||
@NotNull ArrangementTreeNode root,
|
||||
@NotNull ArrangementSettingsGrouper grouper,
|
||||
@@ -92,14 +92,14 @@ public class ArrangementRuleEditingModelBuilder {
|
||||
initialInsertRow--;
|
||||
}
|
||||
|
||||
HierarchicalArrangementSettingsNode grouped = grouper.group(setting);
|
||||
HierarchicalArrangementConditionNode grouped = grouper.group(matchCondition);
|
||||
DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
|
||||
Pair<ArrangementTreeNode, Integer> pair = ArrangementConfigUtil.map(root, grouped, treeModel);
|
||||
ArrangementTreeNode topMostNode = ArrangementConfigUtil.getLastBefore(pair.first, root);
|
||||
int row = initialInsertRow + pair.second - 1;
|
||||
ArrangementRuleEditingModelImpl model = new ArrangementRuleEditingModelImpl(
|
||||
treeModel,
|
||||
setting,
|
||||
matchCondition,
|
||||
topMostNode,
|
||||
pair.first,
|
||||
grouper,
|
||||
|
||||
+35
-35
@@ -41,14 +41,14 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
@NotNull private final Set<Listener> myListeners = new HashSet<Listener>();
|
||||
@NotNull private final Set<Object> myConditions = new HashSet<Object>();
|
||||
|
||||
@NotNull private final DefaultTreeModel myTreeModel;
|
||||
@NotNull private final ArrangementSettingsGrouper myGrouper;
|
||||
private final boolean myRootVisible;
|
||||
@NotNull private final DefaultTreeModel myTreeModel;
|
||||
@NotNull private final ArrangementSettingsGrouper myGrouper;
|
||||
private final boolean myRootVisible;
|
||||
|
||||
@NotNull private ArrangementTreeNode myTopMost;
|
||||
@NotNull private ArrangementTreeNode myBottomMost;
|
||||
@NotNull private ArrangementSettingsNode mySettingsNode;
|
||||
private int myRow;
|
||||
@NotNull private ArrangementTreeNode myTopMost;
|
||||
@NotNull private ArrangementTreeNode myBottomMost;
|
||||
@NotNull private ArrangementMatchCondition myMatchCondition;
|
||||
private int myRow;
|
||||
|
||||
/**
|
||||
* Creates new <code>ArrangementRuleEditingModelImpl</code> object.
|
||||
@@ -57,7 +57,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
* to generate corresponding events automatically
|
||||
* @param node backing settings node
|
||||
* @param topMost there is a possible case that a single settings node is shown in more than one visual line
|
||||
* ({@link HierarchicalArrangementSettingsNode}). This argument is the top-most UI node used for the
|
||||
* ({@link HierarchicalArrangementConditionNode}). This argument is the top-most UI node used for the
|
||||
* settings node representation
|
||||
* @param bottomMost bottom-most UI node used for the given settings node representation
|
||||
* @param grouper strategy that encapsulates information on how settings node should be displayed
|
||||
@@ -65,7 +65,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
* @param rootVisible determines if the root should be count during rows calculations
|
||||
*/
|
||||
public ArrangementRuleEditingModelImpl(@NotNull DefaultTreeModel model,
|
||||
@NotNull ArrangementSettingsNode node,
|
||||
@NotNull ArrangementMatchCondition node,
|
||||
@NotNull ArrangementTreeNode topMost,
|
||||
@NotNull ArrangementTreeNode bottomMost,
|
||||
@NotNull ArrangementSettingsGrouper grouper,
|
||||
@@ -73,7 +73,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
boolean rootVisible)
|
||||
{
|
||||
myTreeModel = model;
|
||||
mySettingsNode = node;
|
||||
myMatchCondition = node;
|
||||
myTopMost = topMost;
|
||||
myBottomMost = bottomMost;
|
||||
myGrouper = grouper;
|
||||
@@ -86,7 +86,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
myConditions.clear();
|
||||
CONDITIONS_BUILDER.conditions = myConditions;
|
||||
try {
|
||||
mySettingsNode.invite(CONDITIONS_BUILDER);
|
||||
myMatchCondition.invite(CONDITIONS_BUILDER);
|
||||
}
|
||||
finally {
|
||||
CONDITIONS_BUILDER.conditions = null;
|
||||
@@ -95,8 +95,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsNode getSettingsNode() {
|
||||
return mySettingsNode;
|
||||
public ArrangementMatchCondition getMatchCondition() {
|
||||
return myMatchCondition;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
@@ -129,8 +129,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
// No refresh is necessary.
|
||||
return;
|
||||
}
|
||||
ArrangementSettingsNode setting = myTopMost.getBackingSetting();
|
||||
if (setting != null && setting.equals(node.getBackingSetting())) {
|
||||
ArrangementMatchCondition matchCondition = myTopMost.getBackingSetting();
|
||||
if (matchCondition != null && matchCondition.equals(node.getBackingSetting())) {
|
||||
myTopMost = node;
|
||||
return;
|
||||
}
|
||||
@@ -139,45 +139,45 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAndCondition(@NotNull ArrangementSettingsAtomNode node) {
|
||||
TIntIntHashMap rowChanges = doAddAndCondition(node);
|
||||
public void addAndCondition(@NotNull ArrangementAtomMatchCondition condition) {
|
||||
TIntIntHashMap rowChanges = doAddAndCondition(condition);
|
||||
refreshConditions();
|
||||
notifyListeners(rowChanges);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TIntIntHashMap doAddAndCondition(@NotNull ArrangementSettingsAtomNode node) {
|
||||
ArrangementSettingsNode newNode = ArrangementUtil.and(mySettingsNode.clone(), node);
|
||||
return applyNewSetting(newNode);
|
||||
private TIntIntHashMap doAddAndCondition(@NotNull ArrangementAtomMatchCondition condition) {
|
||||
ArrangementMatchCondition newNode = ArrangementUtil.and(myMatchCondition.clone(), condition);
|
||||
return applyNewCondition(newNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAndCondition(@NotNull ArrangementSettingsNode node) {
|
||||
TIntIntHashMap rowChanges = doRemoveAndCondition(node);
|
||||
public void removeAndCondition(@NotNull ArrangementMatchCondition condition) {
|
||||
TIntIntHashMap rowChanges = doRemoveAndCondition(condition);
|
||||
refreshConditions();
|
||||
notifyListeners(rowChanges);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TIntIntHashMap doRemoveAndCondition(@NotNull ArrangementSettingsNode node) {
|
||||
if (!(mySettingsNode instanceof ArrangementSettingsCompositeNode)) {
|
||||
private TIntIntHashMap doRemoveAndCondition(@NotNull ArrangementMatchCondition node) {
|
||||
if (!(myMatchCondition instanceof ArrangementCompositeMatchCondition)) {
|
||||
return EMPTY_CHANGES;
|
||||
}
|
||||
|
||||
ArrangementSettingsNode newNode = mySettingsNode.clone();
|
||||
ArrangementSettingsCompositeNode composite = (ArrangementSettingsCompositeNode)newNode;
|
||||
ArrangementMatchCondition newNode = myMatchCondition.clone();
|
||||
ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)newNode;
|
||||
composite.getOperands().remove(node);
|
||||
if (composite.getOperands().size() == 1) {
|
||||
newNode = composite.getOperands().iterator().next();
|
||||
}
|
||||
|
||||
return applyNewSetting(newNode);
|
||||
return applyNewCondition(newNode);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TIntIntHashMap applyNewSetting(@NotNull ArrangementSettingsNode newNode) {
|
||||
mySettingsNode = newNode;
|
||||
HierarchicalArrangementSettingsNode grouped = myGrouper.group(newNode);
|
||||
private TIntIntHashMap applyNewCondition(@NotNull ArrangementMatchCondition newNode) {
|
||||
myMatchCondition = newNode;
|
||||
HierarchicalArrangementConditionNode grouped = myGrouper.group(newNode);
|
||||
int newDepth = ArrangementConfigUtil.getDepth(grouped);
|
||||
int oldDepth = ArrangementConfigUtil.distance(myTopMost, myBottomMost);
|
||||
if (oldDepth == newDepth) {
|
||||
@@ -210,7 +210,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "model for " + mySettingsNode;
|
||||
return "model for " + myMatchCondition;
|
||||
}
|
||||
|
||||
private static class MyConditionsBuilder implements ArrangementSettingsNodeVisitor {
|
||||
@@ -218,13 +218,13 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
@NotNull Set<Object> conditions;
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsAtomNode node) {
|
||||
conditions.add(node.getValue());
|
||||
public void visit(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
conditions.add(setting.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ArrangementSettingsCompositeNode node) {
|
||||
for (ArrangementSettingsNode operand : node.getOperands()) {
|
||||
public void visit(@NotNull ArrangementCompositeMatchCondition setting) {
|
||||
for (ArrangementMatchCondition operand : setting.getOperands()) {
|
||||
operand.invite(this);
|
||||
}
|
||||
}
|
||||
|
||||
+68
-33
@@ -17,13 +17,13 @@ package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsCompositeNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.*;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementSettingsGrouper;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.Consumer;
|
||||
import gnu.trove.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -67,7 +67,12 @@ public class ArrangementRuleTree {
|
||||
private boolean mySkipSelectionChange;
|
||||
|
||||
public ArrangementRuleTree(@NotNull ArrangementSettingsGrouper grouper, @NotNull ArrangementNodeDisplayManager displayManager) {
|
||||
myFactory = new ArrangementNodeComponentFactory(displayManager);
|
||||
myFactory = new ArrangementNodeComponentFactory(displayManager, new Consumer<ArrangementAtomMatchCondition>() {
|
||||
@Override
|
||||
public void consume(@NotNull ArrangementAtomMatchCondition setting) {
|
||||
removeConditionFromActiveModel(setting);
|
||||
}
|
||||
});
|
||||
myRoot = new ArrangementTreeNode(null);
|
||||
myTreeModel = new DefaultTreeModel(myRoot);
|
||||
myTree = new Tree(myTreeModel) {
|
||||
@@ -117,6 +122,12 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
}
|
||||
});
|
||||
myTree.addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
onMouseMoved(e);
|
||||
}
|
||||
});
|
||||
myTree.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
@@ -138,28 +149,28 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
});
|
||||
|
||||
List<ArrangementSettingsNode> rules = new ArrayList<ArrangementSettingsNode>();
|
||||
rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND)
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.STATIC))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.FINAL)));
|
||||
rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND)
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE)));
|
||||
rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND)
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC)));
|
||||
rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND)
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD))
|
||||
.addOperand(new ArrangementSettingsAtomNode(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE)));
|
||||
List<ArrangementMatchCondition> rules = new ArrayList<ArrangementMatchCondition>();
|
||||
rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND)
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.STATIC))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.FINAL)));
|
||||
rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND)
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.FIELD))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE)));
|
||||
rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND)
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PUBLIC)));
|
||||
rules.add(new ArrangementCompositeMatchCondition(ArrangementCompositeMatchCondition.Operator.AND)
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.TYPE, ArrangementEntryType.METHOD))
|
||||
.addOperand(new ArrangementAtomMatchCondition(ArrangementSettingType.MODIFIER, ArrangementModifier.PRIVATE)));
|
||||
map(myRoot, rules, grouper);
|
||||
|
||||
expandAll(myTree, new TreePath(myRoot));
|
||||
myTree.setShowsRootHandles(false);
|
||||
myTree.setCellRenderer(new MyCellRenderer());
|
||||
}
|
||||
|
||||
|
||||
private void selectPreviousRule() {
|
||||
ArrangementTreeNode currentSelectionBottom = getCurrentSelectionBottom();
|
||||
|
||||
@@ -282,12 +293,12 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
private void map(@NotNull ArrangementTreeNode root,
|
||||
@NotNull List<ArrangementSettingsNode> settings,
|
||||
@NotNull List<ArrangementMatchCondition> matchConditions,
|
||||
@NotNull ArrangementSettingsGrouper grouper)
|
||||
{
|
||||
ArrangementRuleEditingModelBuilder builder = new ArrangementRuleEditingModelBuilder();
|
||||
for (ArrangementSettingsNode setting : settings) {
|
||||
builder.build(setting, myTree, root, grouper, myModels);
|
||||
for (ArrangementMatchCondition matchCondition : matchConditions) {
|
||||
builder.build(matchCondition, myTree, root, grouper, myModels);
|
||||
}
|
||||
myModels.forEachValue(new TObjectProcedure<ArrangementRuleEditingModelImpl>() {
|
||||
@Override
|
||||
@@ -330,7 +341,7 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementSettingsNode node) {
|
||||
private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementMatchCondition node) {
|
||||
ArrangementNodeComponent result = myRenderers.get(row);
|
||||
if (result == null) {
|
||||
myRenderers.put(row, result = myFactory.getComponent(node));
|
||||
@@ -338,9 +349,29 @@ public class ArrangementRuleTree {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void removeConditionFromActiveModel(@NotNull ArrangementAtomMatchCondition condition) {
|
||||
ArrangementRuleEditingModel model = getActiveModel();
|
||||
if (model != null) {
|
||||
model.removeAndCondition(condition);
|
||||
notifySelectionListeners(model);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMouseMoved(@NotNull MouseEvent e) {
|
||||
ArrangementNodeComponent component = getNodeComponentAt(e.getLocationOnScreen());
|
||||
if (component == null) {
|
||||
return;
|
||||
}
|
||||
Rectangle changedScreenRectangle = component.handleMouseMove(e);
|
||||
if (changedScreenRectangle != null) {
|
||||
repaintScreenBounds(changedScreenRectangle);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMouseClicked(@NotNull MouseEvent e) {
|
||||
ArrangementNodeComponent component = getNodeComponentAt(e.getLocationOnScreen());
|
||||
if (component != null) {
|
||||
component.handleMouseClick(e);
|
||||
return;
|
||||
}
|
||||
// Clear selection
|
||||
@@ -381,12 +412,16 @@ public class ArrangementRuleTree {
|
||||
private void repaintComponent(@NotNull ArrangementNodeComponent component) {
|
||||
Rectangle bounds = component.getScreenBounds();
|
||||
if (bounds != null) {
|
||||
Point location = bounds.getLocation();
|
||||
SwingUtilities.convertPointFromScreen(location, myTree);
|
||||
myTree.repaint(location.x, location.y, bounds.width, bounds.height);
|
||||
repaintScreenBounds(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
private void repaintScreenBounds(@NotNull Rectangle bounds) {
|
||||
Point location = bounds.getLocation();
|
||||
SwingUtilities.convertPointFromScreen(location, myTree);
|
||||
myTree.repaint(location.x, location.y, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
private void notifySelectionListeners(@Nullable ArrangementRuleEditingModel model) {
|
||||
for (ArrangementRuleSelectionListener listener : myListeners) {
|
||||
if (model == null) {
|
||||
@@ -437,9 +472,9 @@ public class ArrangementRuleTree {
|
||||
myRenderers.remove(row);
|
||||
myTreeModel.nodeChanged(node);
|
||||
mySelectionModel.addSelectionPath(path);
|
||||
ArrangementSettingsNode setting = node.getBackingSetting();
|
||||
if (setting != null) {
|
||||
getNodeComponentAt(row, setting).setSelected(true);
|
||||
ArrangementMatchCondition matchCondition = node.getBackingSetting();
|
||||
if (matchCondition != null) {
|
||||
getNodeComponentAt(row, matchCondition).setSelected(true);
|
||||
}
|
||||
if (node == topMost) {
|
||||
break;
|
||||
@@ -471,7 +506,7 @@ public class ArrangementRuleTree {
|
||||
int row,
|
||||
boolean hasFocus)
|
||||
{
|
||||
ArrangementSettingsNode node = ((ArrangementTreeNode)value).getBackingSetting();
|
||||
ArrangementMatchCondition node = ((ArrangementTreeNode)value).getBackingSetting();
|
||||
if (node == null) {
|
||||
return EMPTY_RENDERER;
|
||||
}
|
||||
@@ -532,7 +567,7 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyModelNodesRefresher implements TObjectProcedure<ArrangementRuleEditingModelImpl> {
|
||||
private static class MyModelNodesRefresher implements TObjectProcedure<ArrangementRuleEditingModelImpl> {
|
||||
@Override
|
||||
public boolean execute(ArrangementRuleEditingModelImpl model) {
|
||||
model.refreshTreeNodes();
|
||||
|
||||
+8
-8
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -31,31 +31,31 @@ public class ArrangementTreeNode extends DefaultMutableTreeNode {
|
||||
|
||||
private static final int NO_ROW = -1;
|
||||
|
||||
@Nullable private ArrangementSettingsNode mySettings;
|
||||
private int myRow;
|
||||
@Nullable private ArrangementMatchCondition mySettings;
|
||||
private int myRow;
|
||||
|
||||
public ArrangementTreeNode(@Nullable ArrangementSettingsNode settings) {
|
||||
public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings) {
|
||||
this(settings, NO_ROW);
|
||||
}
|
||||
|
||||
public ArrangementTreeNode(@Nullable ArrangementSettingsNode settings, int row) {
|
||||
public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings, int row) {
|
||||
mySettings = settings;
|
||||
myRow = row;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ArrangementSettingsNode getBackingSetting() {
|
||||
public ArrangementMatchCondition getBackingSetting() {
|
||||
return mySettings;
|
||||
}
|
||||
|
||||
public void setSettings(@Nullable ArrangementSettingsNode settings) {
|
||||
public void setSettings(@Nullable ArrangementMatchCondition settings) {
|
||||
mySettings = settings;
|
||||
}
|
||||
|
||||
public boolean isRowSet() {
|
||||
return myRow >= 0;
|
||||
}
|
||||
|
||||
|
||||
public int getRow() {
|
||||
return myRow;
|
||||
}
|
||||
|
||||
+1
@@ -179,6 +179,7 @@ public class HighlightUsagesHandler extends HighlightHandlerBase {
|
||||
}
|
||||
|
||||
final EditorSearchComponent header = new EditorSearchComponent(editor, project);
|
||||
header.setRegexp(false);
|
||||
editor.setHeaderComponent(header);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,4 +74,6 @@ public interface ModuleSettings extends ComponentManagerSettings {
|
||||
boolean hasModuleLibrary(String libraryName);
|
||||
|
||||
List<Element> getOrderEntries();
|
||||
|
||||
void addFacetElement(@NotNull String facetTypeId, @NotNull String facetName, Element configuration);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.serialization.JDomSerializationUtil;
|
||||
import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer;
|
||||
|
||||
import java.io.File;
|
||||
@@ -83,6 +84,17 @@ public class ModuleSettingsImpl extends ComponentManagerSettingsImpl implements
|
||||
return ContainerUtil.getFirstItem(getFacetElements(facetTypeId), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFacetElement(@NotNull String facetTypeId, @NotNull String facetName, Element configuration) {
|
||||
Element componentElement = JDomSerializationUtil.findOrCreateComponentElement(getRootElement(), FacetManagerImpl.COMPONENT_NAME);
|
||||
Element facetElement = new Element(JpsFacetSerializer.FACET_TAG);
|
||||
facetElement.setAttribute(JpsFacetSerializer.TYPE_ATTRIBUTE, facetTypeId);
|
||||
facetElement.setAttribute(JpsFacetSerializer.NAME_ATTRIBUTE, facetName);
|
||||
configuration.setName(JpsFacetSerializer.CONFIGURATION_TAG);
|
||||
facetElement.addContent(configuration);
|
||||
componentElement.addContent(facetElement);
|
||||
}
|
||||
|
||||
public void setModuleType(@NotNull String moduleType) {
|
||||
getRootElement().setAttribute(ModuleImpl.ELEMENT_TYPE, moduleType);
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
|
||||
LOG.assertTrue(editor != null);
|
||||
final Document document = editor.getDocument();
|
||||
final int caretOffset = editor.getCaretModel().getOffset();
|
||||
if (caretOffset > -1) {
|
||||
if (caretOffset > -1 && caretOffset < document.getTextLength()) {
|
||||
int line;
|
||||
try {
|
||||
line = document.getLineNumber(caretOffset);
|
||||
|
||||
@@ -128,6 +128,7 @@ public class ExecutionTargetManagerImpl extends ExecutionTargetManager implement
|
||||
private void updateActiveTarget(@Nullable RunnerAndConfigurationSettings settings, @Nullable ExecutionTarget toSelect) {
|
||||
List<ExecutionTarget> suitable = settings == null ? Collections.singletonList(DefaultExecutionTarget.INSTANCE)
|
||||
: getTargetsFor(settings);
|
||||
ExecutionTarget toNotify = null;
|
||||
synchronized (myActiveTargetLock) {
|
||||
if (toSelect == null) toSelect = myActiveTarget;
|
||||
|
||||
@@ -143,18 +144,25 @@ public class ExecutionTargetManagerImpl extends ExecutionTargetManager implement
|
||||
}
|
||||
}
|
||||
}
|
||||
doSetActiveTarget(index >= 0 ? suitable.get(index) : ContainerUtil.getFirstItem(suitable, DefaultExecutionTarget.INSTANCE));
|
||||
toNotify =
|
||||
doSetActiveTarget(index >= 0 ? suitable.get(index) : ContainerUtil.getFirstItem(suitable, DefaultExecutionTarget.INSTANCE));
|
||||
}
|
||||
|
||||
if (toNotify != null) {
|
||||
myProject.getMessageBus().syncPublisher(TOPIC).activeTargetChanged(toNotify);
|
||||
}
|
||||
}
|
||||
|
||||
private void doSetActiveTarget(@NotNull ExecutionTarget newTarget) {
|
||||
@Nullable
|
||||
private ExecutionTarget doSetActiveTarget(@NotNull ExecutionTarget newTarget) {
|
||||
mySavedActiveTargetId = null;
|
||||
|
||||
ExecutionTarget prev = myActiveTarget;
|
||||
myActiveTarget = newTarget;
|
||||
if (prev != null && !prev.equals(myActiveTarget)) {
|
||||
myProject.getMessageBus().syncPublisher(TOPIC).activeTargetChanged(myActiveTarget);
|
||||
return myActiveTarget;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.CommonBundle;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.ui.ComponentWithEmptyText;
|
||||
import com.intellij.util.ui.StatusText;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -82,6 +83,7 @@ public abstract class AddDeleteListPanel<T> extends PanelWithButtons implements
|
||||
protected void customizeDecorator(ToolbarDecorator decorator) {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myList.getEmptyText();
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.ui.ComponentWithEmptyText;
|
||||
import com.intellij.util.ui.StatusText;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -102,6 +103,7 @@ public abstract class AddEditRemovePanel<T> extends PanelWithButtons implements
|
||||
return myLabel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myTable.getEmptyText();
|
||||
|
||||
@@ -20,4 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface ComponentWithExpandableItems<T> {
|
||||
@NotNull
|
||||
ExpandableItemsHandler<T> getExpandableItemsHandler();
|
||||
|
||||
void setExpandableItemsEnabled(boolean enabled);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.ui;
|
||||
|
||||
import com.intellij.util.ui.AbstractLayoutManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ExpandedItemRendererComponentWrapper extends JComponent {
|
||||
public ExpandedItemRendererComponentWrapper(@NotNull final Component rendererComponent) {
|
||||
add(rendererComponent);
|
||||
setOpaque(false);
|
||||
setLayout(new AbstractLayoutManager() {
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
return rendererComponent.getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent) {
|
||||
Dimension size = parent.getSize();
|
||||
Insets i = parent.getInsets();
|
||||
Dimension pref = rendererComponent.getPreferredSize();
|
||||
rendererComponent.setBounds(i.left, i.top, Math.max(pref.width, size.width - i.left - i.right), size.height - i.top - i.bottom);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ public abstract class OptionalChooserComponent<T> implements CheckBoxListListene
|
||||
reset();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myList.getEmptyText();
|
||||
|
||||
@@ -97,6 +97,7 @@ public class PathsChooserComponent implements ComponentWithEmptyText {
|
||||
reset();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myList.getEmptyText();
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ComponentWithExpandableItems;
|
||||
import com.intellij.ui.ExpandableItemsHandler;
|
||||
import com.intellij.ui.ExpandableItemsHandlerFactory;
|
||||
import com.intellij.ui.ExpandedItemRendererComponentWrapper;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
@@ -40,8 +41,8 @@ import java.util.Collection;
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class JBList extends JList implements ComponentWithEmptyText, ComponentWithExpandableItems<Integer>{
|
||||
private StatusText myEmptyText;
|
||||
private ExpandableItemsHandler<Integer> myExpandableItemsHandler;
|
||||
@NotNull private StatusText myEmptyText;
|
||||
@NotNull private ExpandableItemsHandler<Integer> myExpandableItemsHandler;
|
||||
|
||||
@Nullable private AsyncProcessIcon myBusyIcon;
|
||||
private boolean myBusy;
|
||||
@@ -172,15 +173,10 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (shouldInstallItemTooltipExpander()) myExpandableItemsHandler = ExpandableItemsHandlerFactory.install(this);
|
||||
myExpandableItemsHandler = ExpandableItemsHandlerFactory.install(this);
|
||||
setCellRenderer(new DefaultListCellRenderer());
|
||||
}
|
||||
|
||||
protected boolean shouldInstallItemTooltipExpander() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean isEmpty() {
|
||||
return getItemsCount() == 0;
|
||||
}
|
||||
@@ -190,6 +186,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
return model == null ? 0 : model.getSize();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myEmptyText;
|
||||
@@ -201,6 +198,25 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
return myExpandableItemsHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandableItemsEnabled(boolean enabled) {
|
||||
myExpandableItemsHandler.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCellRenderer(final ListCellRenderer cellRenderer) {
|
||||
super.setCellRenderer(new ListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Component result = cellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if (myExpandableItemsHandler != null && myExpandableItemsHandler.getExpandedItems().contains(index)) {
|
||||
result = new ExpandedItemRendererComponentWrapper(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public <T> void installCellRenderer(@NotNull final NotNullFunction<T, JComponent> fun) {
|
||||
setCellRenderer(new DefaultListCellRenderer() {
|
||||
@NotNull
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.ui.components;
|
||||
|
||||
import com.intellij.util.ui.ComponentWithEmptyText;
|
||||
import com.intellij.util.ui.StatusText;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -59,6 +60,7 @@ public class JBTextField extends JTextField implements ComponentWithEmptyText {
|
||||
myEmptyText.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myEmptyText;
|
||||
|
||||
@@ -18,10 +18,7 @@ package com.intellij.ui.table;
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.ComponentWithExpandableItems;
|
||||
import com.intellij.ui.ExpandableItemsHandler;
|
||||
import com.intellij.ui.ExpandableItemsHandlerFactory;
|
||||
import com.intellij.ui.TableCell;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBViewport;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchSupply;
|
||||
import com.intellij.util.ui.*;
|
||||
@@ -300,6 +297,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myEmptyText;
|
||||
@@ -311,6 +309,11 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
return myExpandableItemsHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandableItemsEnabled(boolean enabled) {
|
||||
myExpandableItemsHandler.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void removeNotify() {
|
||||
final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
//noinspection HardCodedStringLiteral
|
||||
@@ -460,12 +463,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
|
||||
private static boolean isTableDecorationSupported() {
|
||||
return UIUtil.isUnderAlloyLookAndFeel()
|
||||
|| UIUtil.isUnderNativeMacLookAndFeel()
|
||||
|| UIUtil.isUnderDarcula()
|
||||
|| UIUtil.isUnderQuaquaLookAndFeel()
|
||||
|| UIUtil.isUnderMetalLookAndFeel()
|
||||
|| UIUtil.isUnderNimbusLookAndFeel()
|
||||
|| UIUtil.isUnderWindowsLookAndFeel();
|
||||
|| UIUtil.isUnderNativeMacLookAndFeel()
|
||||
|| UIUtil.isUnderDarcula()
|
||||
|| UIUtil.isUnderQuaquaLookAndFeel()
|
||||
|| UIUtil.isUnderMetalLookAndFeel()
|
||||
|| UIUtil.isUnderNimbusLookAndFeel()
|
||||
|| UIUtil.isUnderWindowsLookAndFeel();
|
||||
}
|
||||
|
||||
public void disableTypeAheadInCellEditors() {
|
||||
@@ -474,8 +477,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
|
||||
@Override
|
||||
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
|
||||
final Component result = super.prepareRenderer(renderer, row, column);
|
||||
final boolean selected = myExpandableItemsHandler.getExpandedItems().contains(new TableCell(row, column));
|
||||
Component result = super.prepareRenderer(renderer, row, column);
|
||||
|
||||
// Fix GTK background
|
||||
if (UIUtil.isUnderGTKLookAndFeel()) {
|
||||
@@ -483,7 +485,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
}
|
||||
|
||||
if (isTableDecorationSupported() && isStriped() && result instanceof JComponent) {
|
||||
final Color bg = row % 2 == 1 ? getBackground() : UIUtil.getDecoratedRowColor();
|
||||
final Color bg = row % 2 == 1 ? getBackground() : UIUtil.getDecoratedRowColor();
|
||||
final JComponent c = (JComponent)result;
|
||||
final boolean cellSelected = isCellSelected(row, column);
|
||||
if (!cellSelected) {
|
||||
@@ -492,31 +494,13 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
|
||||
for (Component child : c.getComponents()) {
|
||||
child.setBackground(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!selected) return result;
|
||||
|
||||
return new JComponent() {
|
||||
{
|
||||
add(result);
|
||||
setOpaque(false);
|
||||
setLayout(new AbstractLayoutManager() {
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
return result.getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent) {
|
||||
Dimension size = parent.getSize();
|
||||
Insets i = parent.getInsets();
|
||||
Dimension pref = result.getPreferredSize();
|
||||
result.setBounds(i.left, i.top, Math.max(pref.width, size.width - i.left - i.right), size.height - i.top - i.bottom);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if (myExpandableItemsHandler.getExpandedItems().contains(new TableCell(row, column))) {
|
||||
result = new ExpandedItemRendererComponentWrapper(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private final class MyCellEditorRemover implements PropertyChangeListener {
|
||||
|
||||
@@ -148,6 +148,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myEmptyText;
|
||||
@@ -159,6 +160,11 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
|
||||
return myExpandableItemsHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandableItemsEnabled(boolean enabled) {
|
||||
myExpandableItemsHandler.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
return isBackgroundSet() ? super.getBackground() : UIUtil.getTreeTextBackground();
|
||||
|
||||
@@ -209,8 +209,8 @@ public class QueueProcessor<T> {
|
||||
try {
|
||||
LOG.error(t);
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
// should survive assertions
|
||||
catch (Throwable e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface ComponentWithEmptyText {
|
||||
StatusText getEmptyText();
|
||||
@NotNull StatusText getEmptyText();
|
||||
}
|
||||
|
||||
@@ -442,7 +442,8 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
new NameFilteringListModel<FileInfo>(files, new Function<FileInfo, String>() {
|
||||
@Override
|
||||
public String fun(FileInfo info) {
|
||||
return info.getFirst().getName();
|
||||
final VirtualFile file = info.getFirst();
|
||||
return file instanceof VirtualFilePathWrapper ? ((VirtualFilePathWrapper)file).getPresentablePath() : file.getName();
|
||||
}
|
||||
}, new Condition<String>() {
|
||||
@Override
|
||||
@@ -513,6 +514,13 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
}).createPopup();
|
||||
|
||||
if (isPinnedMode()) {
|
||||
new AnAction(null ,null ,null) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
changeSelection();
|
||||
}
|
||||
}.registerCustomShortcutSet(CustomShortcutSet.fromString("TAB"), this, myPopup);
|
||||
|
||||
new AnAction(null, null, null) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
@@ -625,11 +633,15 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
break;
|
||||
}
|
||||
if (e.getKeyCode() == ALT_KEY) {
|
||||
if (isFilesSelected()) {
|
||||
goLeft();
|
||||
} else {
|
||||
goRight();
|
||||
}
|
||||
changeSelection();
|
||||
}
|
||||
}
|
||||
|
||||
private void changeSelection() {
|
||||
if (isFilesSelected()) {
|
||||
goLeft();
|
||||
} else {
|
||||
goRight();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,6 +883,15 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
setComparator(new SpeedSearchComparator(false, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processKeyEvent(KeyEvent e) {
|
||||
final int keyCode = e.getKeyCode();
|
||||
if (keyCode == VK_LEFT || keyCode == VK_RIGHT) {
|
||||
return;
|
||||
}
|
||||
super.processKeyEvent(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSelectedIndex() {
|
||||
return isFilesSelected()
|
||||
@@ -905,10 +926,13 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
|
||||
@Override
|
||||
protected String getElementText(Object element) {
|
||||
return element instanceof ToolWindow
|
||||
? ids.get(element)
|
||||
: element instanceof FileInfo
|
||||
? ((FileInfo)element).getFirst().getName() : "";
|
||||
if (element instanceof ToolWindow) {
|
||||
return ids.get(element);
|
||||
} else if (element instanceof FileInfo) {
|
||||
final VirtualFile file = ((FileInfo)element).getFirst();
|
||||
return file instanceof VirtualFilePathWrapper ? ((VirtualFilePathWrapper)file).getPresentablePath() : file.getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -147,6 +147,7 @@ public class ElementsChooser<T> extends JPanel implements ComponentWithEmptyText
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, KeyEvent.SHIFT_DOWN_MASK), "selectLastRowExtendSelection");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myTable.getEmptyText();
|
||||
@@ -158,6 +159,11 @@ public class ElementsChooser<T> extends JPanel implements ComponentWithEmptyText
|
||||
return myTable.getExpandableItemsHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandableItemsEnabled(boolean enabled) {
|
||||
myTable.setExpandableItemsEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setSingleSelectionMode() {
|
||||
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
}
|
||||
|
||||
@@ -185,11 +185,12 @@ public class CommandMerger {
|
||||
}
|
||||
|
||||
private boolean affectsMultiplePhysicalDocs() {
|
||||
int count = 0;
|
||||
Set<VirtualFile> affectedFiles = new HashSet<VirtualFile>();
|
||||
for (DocumentReference each : myAllAffectedDocuments) {
|
||||
VirtualFile file = each.getFile();
|
||||
if (file instanceof LightVirtualFile) continue;
|
||||
if (++count > 1) return true;
|
||||
if (file == null || file instanceof LightVirtualFile) continue;
|
||||
affectedFiles.add(file);
|
||||
if (affectedFiles.size() > 1) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,8 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen
|
||||
|
||||
private JTextField createColorField(boolean hex) {
|
||||
final NumberDocument doc = new NumberDocument(hex);
|
||||
final JTextField field = new JTextField(doc, "", hex ? 5:2);
|
||||
final int lafFix = UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderWindowsLookAndFeel() ? 1 : 0;
|
||||
final JTextField field = new JTextField(doc, "", (hex ? 5:2) + lafFix);
|
||||
field.setSize(50, -1);
|
||||
doc.setSource(field);
|
||||
field.getDocument().addDocumentListener(this);
|
||||
|
||||
@@ -289,7 +289,7 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
manageSearchPopup(null);
|
||||
}
|
||||
|
||||
private void processKeyEvent(KeyEvent e) {
|
||||
protected void processKeyEvent(KeyEvent e) {
|
||||
if (e.isAltDown()) return;
|
||||
if (mySearchPopup != null) {
|
||||
mySearchPopup.processKeyEvent(e);
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.table.TableView;
|
||||
import com.intellij.util.IconUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -166,6 +167,7 @@ public abstract class ValidatingTableEditor<Item> implements ComponentWithEmptyT
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatusText getEmptyText() {
|
||||
return myTable.getEmptyText();
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.MinusculeMatcher;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.ui.SpeedSearchComparator;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.intellij.util.text.Matcher;
|
||||
@@ -519,4 +520,12 @@ public class NameUtilTest extends UsefulTestCase {
|
||||
}
|
||||
}).cpuBound().attempts(20).assertTiming();
|
||||
}
|
||||
|
||||
public void testSpeedSearchComparator() {
|
||||
final SpeedSearchComparator c = new SpeedSearchComparator(false, true);
|
||||
|
||||
assertTrue(c.matchingFragments("a", "Ant") != null);
|
||||
assertTrue(c.matchingFragments("an", "Changes") != null);
|
||||
assertTrue(c.matchingFragments("a", "Changes") != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ create.global.library=Create Glob&al library ''{0}''
|
||||
create.library.dialog.title=Create Android library
|
||||
select.target.dialog.text=Please select Android Target
|
||||
default.activity.not.found.error=Default Activity not found
|
||||
activity.not.launchable.error=The Intent Filter of the Activity must contain {0} action
|
||||
activity.not.launchable.error=The intent-filter of the activity must contain {0} action
|
||||
activity.not.declared.in.manifest=The activity ''{0}'' is not declared in AndroidManifest.xml
|
||||
new.typed.resource.command.name=New {0} resource file
|
||||
new.typed.resource.dialog.title=New {0} Resource File
|
||||
new.file.dialog.text=Enter a new file name
|
||||
|
||||
@@ -50,7 +50,7 @@ public class AndroidDependencyProcessor implements DependencyProcessor {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiClass[] classes =
|
||||
JavaPsiFacade.getInstance(project).findClasses(topLevelClassName, GlobalSearchScope.allScope(project));
|
||||
JavaPsiFacade.getInstance(project).findClasses(topLevelClassName, GlobalSearchScope.projectScope(project));
|
||||
|
||||
for (PsiClass aClass : classes) {
|
||||
final Collection<PsiReference> references = searcher.findReferences(aClass, true);
|
||||
|
||||
+2
-1
@@ -116,7 +116,8 @@ public class AndroidResourceReferenceBase extends PsiReferenceBase.Poly<XmlEleme
|
||||
if (manager != null) {
|
||||
String resName = resValue.getResourceName();
|
||||
if (resName != null) {
|
||||
List<ValueResourceInfoImpl> valueResources = manager.findValueResourceInfos(resType, resName, false);
|
||||
final boolean attrReference = resValue.getPrefix() == '?';
|
||||
List<ValueResourceInfoImpl> valueResources = manager.findValueResourceInfos(resType, resName, false, attrReference);
|
||||
|
||||
for (final ValueResourceInfo resource : valueResources) {
|
||||
elements.add(new LazyValueResourceElementWrapper(resource, myElement));
|
||||
|
||||
@@ -23,5 +23,6 @@ import com.android.resources.ResourceType;
|
||||
public class ParentStyleConverter extends ResourceReferenceConverter {
|
||||
public ParentStyleConverter() {
|
||||
super(ResourceType.STYLE.getName(), false, false);
|
||||
setAllowAttributeReferences(false);
|
||||
}
|
||||
}
|
||||
|
||||
+56
-12
@@ -55,6 +55,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
private boolean myWithPrefix = true;
|
||||
private boolean myWithExplicitResourceType = true;
|
||||
private boolean myQuiet = false;
|
||||
private boolean myAllowAttributeReferences = true;
|
||||
|
||||
public ResourceReferenceConverter() {
|
||||
this(new ArrayList<String>());
|
||||
@@ -79,6 +80,10 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
myQuiet = quiet;
|
||||
}
|
||||
|
||||
public void setAllowAttributeReferences(boolean allowAttributeReferences) {
|
||||
myAllowAttributeReferences = allowAttributeReferences;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getPackagePrefix(@Nullable String resourcePackage) {
|
||||
String prefix = myWithPrefix ? "@" : "";
|
||||
@@ -126,10 +131,12 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
else {
|
||||
result.add(ResourceValue.literal(systemPrefix));
|
||||
}
|
||||
final char prefix = myWithPrefix ? '@' : 0;
|
||||
|
||||
if (recommendedTypes.size() == 1) {
|
||||
String type = recommendedTypes.iterator().next();
|
||||
boolean explicitResourceType = value.startsWith(getTypePrefix(resourcePackage, type)) || myWithExplicitResourceType;
|
||||
addResourceReferenceValues(facet, type, resourcePackage, result, explicitResourceType);
|
||||
addResourceReferenceValues(facet, prefix, type, resourcePackage, result, explicitResourceType);
|
||||
}
|
||||
else {
|
||||
final Set<String> filteringSet = SYSTEM_RESOURCE_PACKAGE.equals(resourcePackage)
|
||||
@@ -140,7 +147,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
final String type = resourceType.getName();
|
||||
String typePrefix = getTypePrefix(resourcePackage, type);
|
||||
if (value.startsWith(typePrefix)) {
|
||||
addResourceReferenceValues(facet, type, resourcePackage, result, true);
|
||||
addResourceReferenceValues(facet, prefix, type, resourcePackage, result, true);
|
||||
}
|
||||
else if (recommendedTypes.contains(type) &&
|
||||
(filteringSet == null || filteringSet.contains(type))) {
|
||||
@@ -149,6 +156,9 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myAllowAttributeReferences) {
|
||||
completeAttributeReferences(value, facet, result);
|
||||
}
|
||||
final ResolvingConverter<String> additionalConverter = getAdditionalConverter(context);
|
||||
|
||||
if (additionalConverter != null) {
|
||||
@@ -159,6 +169,19 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void completeAttributeReferences(String value, AndroidFacet facet, Set<ResourceValue> result) {
|
||||
if (StringUtil.startsWith(value, "?attr/")) {
|
||||
addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), null, result, true);
|
||||
}
|
||||
else if (StringUtil.startsWith(value, "?android:attr/")) {
|
||||
addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), SYSTEM_RESOURCE_PACKAGE, result, true);
|
||||
}
|
||||
else if (StringUtil.startsWithChar(value, '?')) {
|
||||
addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), null, result, false);
|
||||
addResourceReferenceValues(facet, '?', ResourceType.ATTR.getName(), SYSTEM_RESOURCE_PACKAGE, result, false);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<String> getResourceTypesInCurrentModule(@NotNull AndroidFacet facet) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
@@ -205,21 +228,22 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
return types;
|
||||
}
|
||||
|
||||
private void addResourceReferenceValues(AndroidFacet facet,
|
||||
String type,
|
||||
String resPackage,
|
||||
Collection<ResourceValue> result,
|
||||
boolean explicitResourceType) {
|
||||
private static void addResourceReferenceValues(AndroidFacet facet,
|
||||
char prefix,
|
||||
String type,
|
||||
@Nullable String resPackage,
|
||||
Collection<ResourceValue> result,
|
||||
boolean explicitResourceType) {
|
||||
final ResourceManager manager = facet.getResourceManager(resPackage);
|
||||
if (manager != null) {
|
||||
for (String name : manager.getResourceNames(type)) {
|
||||
result.add(referenceTo(type, resPackage, name, explicitResourceType));
|
||||
result.add(referenceTo(prefix, type, resPackage, name, explicitResourceType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceValue referenceTo(String type, String resPackage, String name, boolean explicitResourceType) {
|
||||
return ResourceValue.referenceTo(myWithPrefix ? '@' : 0, resPackage, explicitResourceType ? type : null, name);
|
||||
private static ResourceValue referenceTo(char prefix, String type, String resPackage, String name, boolean explicitResourceType) {
|
||||
return ResourceValue.referenceTo(prefix, resPackage, explicitResourceType ? type : null, name);
|
||||
}
|
||||
|
||||
public ResourceValue fromString(@Nullable @NonNls String s, ConvertContext context) {
|
||||
@@ -236,8 +260,28 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (parsed != null && parsed.getResourceType() == null && myResourceTypes.size() == 1) {
|
||||
parsed.setResourceType(myResourceTypes.get(0));
|
||||
if (parsed != null) {
|
||||
final String resType = parsed.getResourceType();
|
||||
|
||||
if (parsed.getPrefix() == '?') {
|
||||
if (!myAllowAttributeReferences) {
|
||||
return null;
|
||||
}
|
||||
if (resType == null) {
|
||||
parsed.setResourceType(ResourceType.ATTR.getName());
|
||||
}
|
||||
else if (!ResourceType.ATTR.getName().equals(resType)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (resType == null && parsed.isReference()) {
|
||||
if (myWithExplicitResourceType && !"@null".equals(s)) {
|
||||
return null;
|
||||
}
|
||||
if (myResourceTypes.size() == 1) {
|
||||
parsed.setResourceType(myResourceTypes.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ResourceValue {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
if (s.startsWith("@")) {
|
||||
if (s.startsWith("@") || s.startsWith("?")) {
|
||||
return reference(s, true);
|
||||
}
|
||||
else if (!withPrefix) {
|
||||
@@ -92,9 +92,11 @@ public class ResourceValue {
|
||||
assert value.length() > 0;
|
||||
result.myPrefix = value.charAt(0);
|
||||
}
|
||||
final int startIndex = withPrefix ? 1 : 0;
|
||||
int pos = value.indexOf('/');
|
||||
|
||||
if (pos > 0) {
|
||||
String resType = value.substring(withPrefix ? 1 : 0, pos);
|
||||
String resType = value.substring(startIndex, pos);
|
||||
int colonIndex = resType.indexOf(':');
|
||||
if (colonIndex > 0) {
|
||||
result.myPackage = resType.substring(0, colonIndex);
|
||||
@@ -117,10 +119,13 @@ public class ResourceValue {
|
||||
}
|
||||
else {
|
||||
int colonIndex = value.indexOf(':');
|
||||
if (colonIndex > 0) {
|
||||
result.myPackage = value.substring(0, colonIndex);
|
||||
if (colonIndex > startIndex) {
|
||||
result.myPackage = value.substring(startIndex, colonIndex);
|
||||
result.myResourceName = value.substring(colonIndex + 1);
|
||||
}
|
||||
else {
|
||||
result.myResourceName = value.substring(startIndex);
|
||||
}
|
||||
result.myResourceName = value.substring(colonIndex + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ public abstract class ResourceManager {
|
||||
public List<ResourceElement> findValueResources(@NotNull String resourceType,
|
||||
@NotNull String resourceName,
|
||||
boolean distinguishDelimitersInName) {
|
||||
final List<ValueResourceInfoImpl> resources = findValueResourceInfos(resourceType, resourceName, distinguishDelimitersInName);
|
||||
final List<ValueResourceInfoImpl> resources = findValueResourceInfos(resourceType, resourceName, distinguishDelimitersInName, false);
|
||||
final List<ResourceElement> result = new ArrayList<ResourceElement>();
|
||||
|
||||
for (ValueResourceInfoImpl resource : resources) {
|
||||
@@ -449,14 +449,14 @@ public abstract class ResourceManager {
|
||||
@NotNull
|
||||
public List<ValueResourceInfoImpl> findValueResourceInfos(@NotNull String resourceType,
|
||||
@NotNull final String resourceName,
|
||||
final boolean distinguishDelimetersInName) {
|
||||
final boolean distinguishDelimetersInName,
|
||||
boolean searchAttrs) {
|
||||
final ResourceType type = ResourceType.getEnum(resourceType);
|
||||
if (type == null || !AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(type)) {
|
||||
// do not search for styleables and atts here because we don't want to resolve references to it
|
||||
if (type == null ||
|
||||
!AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(type) &&
|
||||
(type != ResourceType.ATTR || !searchAttrs)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
new HashMap<VirtualFile, Set<AndroidValueResourcesIndex.MyResourceInfo>>();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(myModule.getProject());
|
||||
final List<ValueResourceInfoImpl> result = new ArrayList<ValueResourceInfoImpl>();
|
||||
final Set<VirtualFile> valueResourceFiles = getAllValueResourceFiles();
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -82,7 +81,12 @@ public class AndroidRunConfiguration extends AndroidRunConfigurationBase impleme
|
||||
if (!c.isInheritor(activityClass, true)) {
|
||||
throw new RuntimeConfigurationError(AndroidBundle.message("not.activity.subclass.error", ACTIVITY_CLASS));
|
||||
}
|
||||
if (!isActivityLaunchable(facet.getModule(), c)) {
|
||||
|
||||
final Activity activity = AndroidDomUtil.getActivityDomElementByClass(facet.getModule(), c);
|
||||
if (activity == null) {
|
||||
throw new RuntimeConfigurationError(AndroidBundle.message("activity.not.declared.in.manifest", c.getName()));
|
||||
}
|
||||
if (!isActivityLaunchable(activity)) {
|
||||
throw new RuntimeConfigurationError(AndroidBundle.message("activity.not.launchable.error", AndroidUtils.LAUNCH_ACTION_NAME));
|
||||
}
|
||||
}
|
||||
@@ -170,13 +174,10 @@ public class AndroidRunConfiguration extends AndroidRunConfigurationBase impleme
|
||||
return new MyApplicationLauncher(activityToLaunch);
|
||||
}
|
||||
|
||||
private static boolean isActivityLaunchable(@NotNull Module module, PsiClass c) {
|
||||
Activity activity = AndroidDomUtil.getActivityDomElementByClass(module, c);
|
||||
if (activity != null) {
|
||||
for (IntentFilter filter : activity.getIntentFilters()) {
|
||||
if (AndroidDomUtil.containsAction(filter, AndroidUtils.LAUNCH_ACTION_NAME)) {
|
||||
return true;
|
||||
}
|
||||
private static boolean isActivityLaunchable(Activity activity) {
|
||||
for (IntentFilter filter : activity.getIntentFilters()) {
|
||||
if (AndroidDomUtil.containsAction(filter, AndroidUtils.LAUNCH_ACTION_NAME)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?myAttr"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?otherAttr"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>?unknown</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/myAttr"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>?attr/unknown</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>@attr/myAttr</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>@myAttr</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/myDrawable"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>?drawable/myDrawable</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:text"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<error>?android:unknown</error>"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/text"/>
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="</error>?android:attr/unknown</error>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/myAttr"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/textAppearance"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?myAttr"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?<caret>"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:textAppearance"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,9 @@
|
||||
<resources>
|
||||
<attr name="myAttr" format="integer"/>
|
||||
|
||||
<declare-styleable name="MyCustomView">
|
||||
<attr name="otherAttr" format="integer"/>
|
||||
</declare-styleable>
|
||||
|
||||
<drawable name="myDrawable"/>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<attr name="myAttr" format="integer"/>
|
||||
|
||||
<style name="myStyle" parent="?<caret>">
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<attr name="myAttr" format="integer"/>
|
||||
|
||||
<style name="myStyle" parent="?">
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,20 @@
|
||||
<resources>
|
||||
<attr name="myAttr" format="integer"/>
|
||||
|
||||
<style name="myStyle1" parent="<error>?myAttr</error>">
|
||||
</style>
|
||||
<style name="myStyle2" parent="<error>?attr/myAttr</error>">
|
||||
</style>
|
||||
<style name="myStyle3" parent="<error>attr/myAttr</error>">
|
||||
</style>
|
||||
<style name="myStyle4" parent="<error>myAttr</error>">
|
||||
</style>
|
||||
<style name="myStyle5" parent="<error>android:textAppearance</error>">
|
||||
</style>
|
||||
<style name="myStyle6" parent="<error>android:attr/textAppearance</error>">
|
||||
</style>
|
||||
<style name="myStyle7" parent="<error>?android:attr/textAppearance</error>">
|
||||
</style>
|
||||
<style name="myStyle8" parent="<error>?android:textAppearance</error>">
|
||||
</style>
|
||||
</resources>
|
||||
@@ -667,6 +667,64 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
|
||||
doTestHighlighting();
|
||||
}
|
||||
|
||||
public void testAttrReferences1() throws Throwable {
|
||||
copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml");
|
||||
doTestHighlighting();
|
||||
}
|
||||
|
||||
public void testAttrReferences2() throws Throwable {
|
||||
doTestAttrReferenceCompletionVariants("?");
|
||||
}
|
||||
|
||||
public void testAttrReferences3() throws Throwable {
|
||||
doTestAttrReferenceCompletionVariants("attr");
|
||||
}
|
||||
|
||||
private void doTestAttrReferenceCompletionVariants(String prefix) throws IOException {
|
||||
copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml");
|
||||
VirtualFile file = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(file);
|
||||
myFixture.complete(CompletionType.BASIC);
|
||||
final List<String> variants = myFixture.getLookupElementStrings();
|
||||
assertNotNull(variants);
|
||||
assertTrue(variants.size() > 0);
|
||||
assertFalse(containElementStartingWith(variants, prefix));
|
||||
}
|
||||
|
||||
public void testAttrReferences4() throws Throwable {
|
||||
doTestAttrReferenceCompletion("myA\n");
|
||||
}
|
||||
|
||||
public void testAttrReferences5() throws Throwable {
|
||||
doTestAttrReferenceCompletion("textAppear\n");
|
||||
}
|
||||
|
||||
public void testAttrReferences6() throws Throwable {
|
||||
doTestAttrReferenceCompletion("myA\n");
|
||||
}
|
||||
|
||||
public void testAttrReferences7() throws Throwable {
|
||||
doTestAttrReferenceCompletion("android:textAppear\n");
|
||||
}
|
||||
|
||||
private void doTestAttrReferenceCompletion(String textToType) throws IOException {
|
||||
copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml");
|
||||
VirtualFile file = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(file);
|
||||
myFixture.complete(CompletionType.BASIC);
|
||||
myFixture.type(textToType);
|
||||
myFixture.checkResultByFile(testFolder + '/' + getTestName(true) + "_after.xml");
|
||||
}
|
||||
|
||||
private static boolean containElementStartingWith(List<String> elements, String prefix) {
|
||||
for (String element : elements) {
|
||||
if (element.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void doCreateFileResourceFromUsage(VirtualFile virtualFile) {
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
final List<HighlightInfo> infos = myFixture.doHighlighting();
|
||||
|
||||
@@ -317,6 +317,14 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
|
||||
myFixture.checkResultByFile("res/values/bools.xml", testFolder + '/' + getTestName(true) + "_bools_after.xml", true);
|
||||
}
|
||||
|
||||
public void testAttrReferenceCompletion() throws Throwable {
|
||||
doTestCompletion();
|
||||
}
|
||||
|
||||
public void testAttrReferenceHighlighting() throws Throwable {
|
||||
doTestHighlighting();
|
||||
}
|
||||
|
||||
private void doCreateValueResourceFromUsage(VirtualFile virtualFile) {
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
final List<HighlightInfo> infos = myFixture.doHighlighting();
|
||||
|
||||
@@ -20,14 +20,19 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vcs.FileStatusManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packageDependencies.DependencyValidationManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -87,9 +92,13 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx
|
||||
|
||||
public void projectOpened() {
|
||||
if (myProject != null) {
|
||||
FileEditorManagerListener listener = new FileEditorManagerAdapter() {
|
||||
public void fileOpened(FileEditorManager fileEditorManager, VirtualFile virtualFile) {
|
||||
if (virtualFile.isWritable() && NewFileTracker.getInstance().contains(virtualFile)) {
|
||||
final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
DocumentListener listener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
final Document document = e.getDocument();
|
||||
final VirtualFile virtualFile = fileDocumentManager.getFile(document);
|
||||
if (virtualFile != null && NewFileTracker.getInstance().contains(virtualFile)) {
|
||||
NewFileTracker.getInstance().remove(virtualFile);
|
||||
if (FileTypeUtil.getInstance().isSupportedFile(virtualFile)) {
|
||||
final Module module = ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(virtualFile);
|
||||
@@ -100,7 +109,7 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
if (file.isValid() && file.isWritable()) {
|
||||
final CopyrightProfile opts = getInstance(myProject).getCopyrightOptions(file);
|
||||
final CopyrightProfile opts = getCopyrightOptions(file);
|
||||
if (opts != null) {
|
||||
new UpdateCopyrightProcessor(myProject, module, file).run();
|
||||
}
|
||||
@@ -113,8 +122,10 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
FileEditorManager.getInstance(myProject).addFileEditorManagerListener(listener, myProject);
|
||||
final EditorFactory factory = EditorFactory.getInstance();
|
||||
if (factory != null) {
|
||||
factory.getEventMulticaster().addDocumentListener(listener, myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -787,7 +787,7 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
|
||||
@Override
|
||||
public DomElement fun(DomStub stub) {
|
||||
if (stub instanceof ElementStub && ((ElementStub)stub).isCustom()) {
|
||||
EvaluatedXmlName name = new DummyEvaluatedXmlName(stub.getName(), null);
|
||||
EvaluatedXmlName name = new DummyEvaluatedXmlName(stub.getName(), "");
|
||||
return new CollectionElementInvocationHandler(name, (CustomDomChildrenDescriptionImpl)description, myManager, (ElementStub)stub).getProxy();
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -27,11 +27,11 @@ public class DummyEvaluatedXmlName implements EvaluatedXmlName {
|
||||
private final XmlName myXmlName;
|
||||
private final String myNamespace;
|
||||
|
||||
public DummyEvaluatedXmlName(final String localName, final String namespace) {
|
||||
public DummyEvaluatedXmlName(final String localName, @NotNull final String namespace) {
|
||||
this(new XmlName(localName), namespace);
|
||||
}
|
||||
|
||||
public DummyEvaluatedXmlName(final XmlName xmlName, final String namespace) {
|
||||
public DummyEvaluatedXmlName(final XmlName xmlName, @NotNull final String namespace) {
|
||||
myXmlName = xmlName;
|
||||
myNamespace = namespace;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user