Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-02-18 15:28:29 +04:00
50 changed files with 1043 additions and 167 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -903,9 +903,12 @@ public class JavaCompletionUtil {
}
if (pkgContext) {
PsiFile classFile = psiClass.getContainingFile();
if (classFile instanceof PsiClassOwner && StringUtil.isEmpty(((PsiClassOwner)classFile).getPackageName())) {
return false;
PsiClass topLevel = PsiUtil.getTopLevelClass(psiClass);
if (topLevel != null) {
String fqName = topLevel.getQualifiedName();
if (fqName != null && StringUtil.isEmpty(StringUtil.getPackageName(fqName))) {
return false;
}
}
}
@@ -490,6 +490,7 @@ public class HighlightUtil {
}
if (expression != null && lType != null) {
QuickFixAction.registerQuickFixAction(highlightInfo, new WrapExpressionFix(lType, expression));
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
}
ChangeNewOperatorTypeFix.register(highlightInfo, expression, lType);
return highlightInfo;
@@ -0,0 +1,153 @@
/*
* 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.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
/**
* User: anna
* Date: 2/17/12
*/
public class AddTypeArgumentsConditionalFix implements IntentionAction {
private static final Logger LOG = Logger.getInstance("#" + AddTypeArgumentsConditionalFix.class.getName());
private final PsiSubstitutor mySubstitutor;
private final PsiMethodCallExpression myExpression;
private final PsiMethod myMethod;
public AddTypeArgumentsConditionalFix(PsiSubstitutor substitutor, PsiMethodCallExpression expression, PsiMethod method) {
mySubstitutor = substitutor;
myExpression = expression;
myMethod = method;
}
@NotNull
@Override
public String getText() {
return "Add explicit type arguments";
}
@NotNull
@Override
public String getFamilyName() {
return getText();
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (mySubstitutor.isValid() && myExpression.isValid() && myMethod.isValid()) {
return true;
}
return false;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiTypeParameter[] typeParameters = myMethod.getTypeParameters();
final String typeArguments = "<" + StringUtil.join(typeParameters, new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter parameter) {
final PsiType substituteTypeParam = mySubstitutor.substitute(parameter);
LOG.assertTrue(substituteTypeParam != null);
return substituteTypeParam.getCanonicalText();
}
}, ", ") + ">";
final PsiExpression expression = myExpression.getMethodExpression().getQualifierExpression();
String withTypeArgsText;
if (expression != null) {
withTypeArgsText = expression.getText();
}
else {
if (RefactoringUtil.isInStaticContext(myExpression, null) || myMethod.hasModifierProperty(PsiModifier.STATIC)) {
final PsiClass aClass = myMethod.getContainingClass();
LOG.assertTrue(aClass != null);
withTypeArgsText = aClass.getQualifiedName();
}
else {
withTypeArgsText = "this";
}
}
withTypeArgsText += "." + typeArguments + myExpression.getMethodExpression().getReferenceName();
final PsiExpression withTypeArgs = JavaPsiFacade.getElementFactory(project).createExpressionFromText(withTypeArgsText + myExpression.getArgumentList().getText(), myExpression);
myExpression.replace(withTypeArgs);
}
@Override
public boolean startInWriteAction() {
return true;
}
public static void register(HighlightInfo highlightInfo, PsiExpression expression, PsiType lType) {
if (expression instanceof PsiConditionalExpression) {
final PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression();
final PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression();
if (thenExpression != null && elseExpression != null) {
final PsiType thenType = thenExpression.getType();
final PsiType elseType = elseExpression.getType();
if (thenType != null && elseType != null) {
final boolean thenAssignable = TypeConversionUtil.isAssignable(lType, thenType);
final boolean elseAssignable = TypeConversionUtil.isAssignable(lType, elseType);
if (!thenAssignable && thenExpression instanceof PsiMethodCallExpression) {
inferTypeArgs(highlightInfo, lType, thenExpression);
}
if (!elseAssignable && elseExpression instanceof PsiMethodCallExpression) {
inferTypeArgs(highlightInfo, lType, elseExpression);
}
}
}
}
}
private static void inferTypeArgs(HighlightInfo highlightInfo, PsiType lType, PsiExpression thenExpression) {
final JavaResolveResult result = ((PsiMethodCallExpression)thenExpression).resolveMethodGenerics();
final PsiMethod method = (PsiMethod)result.getElement();
if (method != null) {
final PsiType returnType = method.getReturnType();
final PsiClass aClass = method.getContainingClass();
if (returnType != null && aClass != null && aClass.getQualifiedName() != null) {
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject());
final PsiDeclarationStatement variableDeclarationStatement =
javaPsiFacade.getElementFactory().createVariableDeclarationStatement("xxx", lType, thenExpression);
final PsiExpression initializer =
((PsiLocalVariable)variableDeclarationStatement.getDeclaredElements()[0]).getInitializer();
LOG.assertTrue(initializer != null);
final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper()
.inferTypeArguments(method.getTypeParameters(), method.getParameterList().getParameters(),
((PsiMethodCallExpression)thenExpression).getArgumentList().getExpressions(), PsiSubstitutor.EMPTY,
initializer, DefaultParameterTypeInferencePolicy.INSTANCE);
PsiType substitutedType = substitutor.substitute(returnType);
if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) {
QuickFixAction.registerQuickFixAction(highlightInfo,
thenExpression.getTextRange(),
new AddTypeArgumentsConditionalFix(substitutor, (PsiMethodCallExpression)thenExpression, method), null);
}
}
}
}
}
@@ -43,6 +43,11 @@ public class CreateConstructorFromCallFix extends CreateFromUsageBaseFix {
myConstructorCall = constructorCall;
}
@Override
protected boolean canBeTargetClass(PsiClass psiClass) {
return false;
}
@Override
protected void invokeImpl(final PsiClass targetClass) {
final Project project = myConstructorCall.getProject();
@@ -80,7 +80,7 @@ public class RefactoringUtil {
return Comparing.equal(virtualFile, sourceRootForFile);
}
public static boolean isInStaticContext(PsiElement element, final PsiClass aClass) {
public static boolean isInStaticContext(PsiElement element, @Nullable final PsiClass aClass) {
return PsiUtil.getEnclosingStaticElement(element, aClass) != null;
}
@@ -579,8 +579,8 @@ public final class PsiUtil extends PsiUtilCore {
@Nullable
public static PsiClass getTopLevelClass(@NotNull PsiElement element) {
final PsiFile file = element.getContainingFile();
if (file instanceof PsiJavaFile) {
final PsiClass[] classes = ((PsiJavaFile)file).getClasses();
if (file instanceof PsiClassOwner) {
final PsiClass[] classes = ((PsiClassOwner)file).getClasses();
for (PsiClass aClass : classes) {
if (PsiTreeUtil.isAncestor(aClass, element, false)) return aClass;
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? Test.<String>f() : f();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
<T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? this.<String>f() : new ArrayList<String>();
}
}
@@ -0,0 +1,13 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
void someMethod(boolean b) {
List<String> s = b ? Foo.<String>f() : new ArrayList<String>();
}
}
class Foo{
static <T> List<T> f() { return new ArrayList<T>(); }
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
<T> List<T> f() { return new ArrayList<T>(); }
void someMethod(Test t, boolean b) {
List<String> s = b ? t.<String>f() : new ArrayList<String>();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(Test t, boolean b) {
List<String> s = b ? t.<String>f() : new ArrayList<String>();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? Test.<String>f() : new ArrayList<String>();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? f<caret>() : f();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
<T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? f<caret>() : new ArrayList<String>();
}
}
@@ -0,0 +1,13 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
void someMethod(boolean b) {
List<String> s = b ? Foo.f<caret>() : new ArrayList<String>();
}
}
class Foo{
static <T> List<T> f() { return new ArrayList<T>(); }
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
<T> List<T> f() { return new ArrayList<T>(); }
void someMethod(Test t, boolean b) {
List<String> s = b ? t.f<caret>() : new ArrayList<String>();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(Test t, boolean b) {
List<String> s = b ? t.f<caret>() : new ArrayList<String>();
}
}
@@ -0,0 +1,9 @@
// "Add explicit type arguments" "true"
import java.util.*;
class Test {
static <T> List<T> f() { return new ArrayList<T>(); }
void someMethod(boolean b) {
List<String> s = b ? f<caret>() : new ArrayList<String>();
}
}
@@ -0,0 +1,26 @@
/*
* 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.codeInsight.daemon.quickFix;
public class AddTypeArgumentsConditionalTest extends LightQuickFix15TestCase {
public void test() throws Exception { doAllTests(); }
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArgumentsConditional";
}
}
@@ -53,7 +53,7 @@ public class ProjectScope {
@NotNull
public static GlobalSearchScope getContentScope(@NotNull Project project) {
GlobalSearchScope cached = project.getUserData(LIBRARIES_SCOPE_KEY);
GlobalSearchScope cached = project.getUserData(CONTENT_SCOPE_KEY);
return cached != null ? cached : ((UserDataHolderEx)project).putUserDataIfAbsent(CONTENT_SCOPE_KEY, ProjectScopeBuilder.getInstance(project).buildContentScope());
}
}
@@ -23,17 +23,21 @@ import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.util.PairConsumer;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpleInspectionTool {
private final boolean highlightErrorElements;
private final boolean runAnnotators;
@@ -86,42 +90,43 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl
}
@Override
public void checkFile(@NotNull PsiFile file,
public void checkFile(@NotNull PsiFile originalFile,
@NotNull final InspectionManager manager,
@NotNull ProblemsHolder problemsHolder,
@NotNull final GlobalInspectionContext globalContext,
@NotNull final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
runGeneralHighlighting(file, highlightErrorElements, runAnnotators, new PairConsumer<PsiFile, HighlightInfo>() {
@Override
public void consume(PsiFile file, HighlightInfo info) {
TextRange range = new TextRange(info.startOffset, info.endOffset);
PsiElement element = file.findElementAt(info.startOffset);
for (Pair<PsiFile, HighlightInfo> pair : runGeneralHighlighting(originalFile, highlightErrorElements, runAnnotators)) {
PsiFile file = pair.first;
HighlightInfo info = pair.second;
TextRange range = new TextRange(info.startOffset, info.endOffset);
PsiElement element = file.findElementAt(info.startOffset);
while (element != null && !element.getTextRange().contains(range)) {
element = element.getParent();
}
if (element == null) {
element = file;
}
GlobalInspectionUtil.createProblem(
element,
info.description,
HighlightInfo.convertType(info.type),
range.shiftRight(-element.getNode().getStartOffset()),
manager,
problemDescriptionsProcessor,
globalContext
);
while (element != null && !element.getTextRange().contains(range)) {
element = element.getParent();
}
});
if (element == null) {
element = file;
}
GlobalInspectionUtil.createProblem(
element,
info.description,
HighlightInfo.convertType(info.type),
range.shiftRight(-element.getNode().getStartOffset()),
manager,
problemDescriptionsProcessor,
globalContext
);
}
}
public static void runGeneralHighlighting(PsiFile file,
public static List<Pair<PsiFile,HighlightInfo>> runGeneralHighlighting(PsiFile file,
final boolean highlightErrorElements,
final boolean runAnnotators,
PairConsumer<PsiFile, HighlightInfo> consumer) {
file.accept(new MyPsiElementVisitor(highlightErrorElements, runAnnotators, consumer));
final boolean runAnnotators) {
MyPsiElementVisitor visitor = new MyPsiElementVisitor(highlightErrorElements, runAnnotators);
file.accept(visitor);
return new ArrayList<Pair<PsiFile, HighlightInfo>>(visitor.result);
}
@Nls
@@ -134,14 +139,11 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl
private static class MyPsiElementVisitor extends PsiElementVisitor {
private final boolean highlightErrorElements;
private final boolean runAnnotators;
private final PairConsumer<PsiFile,HighlightInfo> myConsumer;
final List<Pair<PsiFile,HighlightInfo>> result = ContainerUtil.createEmptyCOWList();
public MyPsiElementVisitor(boolean highlightErrorElements,
boolean runAnnotators, final PairConsumer<PsiFile, HighlightInfo> consumer) {
public MyPsiElementVisitor(boolean highlightErrorElements, boolean runAnnotators) {
this.highlightErrorElements = highlightErrorElements;
this.runAnnotators = runAnnotators;
myConsumer = consumer;
}
@Override
@@ -172,7 +174,7 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl
if (info.type == HighlightInfoType.INJECTED_LANGUAGE_FRAGMENT) return true;
if (info.severity == HighlightSeverity.INFORMATION) return true;
myConsumer.consume(file, info);
result.add(Pair.create(file, info));
return true;
}
@@ -48,6 +48,7 @@ import java.util.*;
* @author max
*/
public abstract class DescriptorProviderInspection extends InspectionTool implements ProblemDescriptionsProcessor {
private static final Object lock = new Object();
private Map<RefEntity, CommonProblemDescriptor[]> myProblemElements;
private HashMap<String, Set<RefEntity>> myContents = null;
private HashSet<RefModule> myModulesProblems = null;
@@ -68,14 +69,12 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
if (descriptions == null || descriptions.length == 0) return;
if (filterSuppressed) {
if (ourOutputPath == null || !(this instanceof LocalInspectionToolWrapper)) {
CommonProblemDescriptor[] problems = getProblemElements().get(refElement);
if (problems == null) {
problems = descriptions;
synchronized (lock) {
Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
CommonProblemDescriptor[] problems = problemElements.get(refElement);
problems = problems == null ? descriptions : ArrayUtil.mergeArrays(problems, descriptions);
problemElements.put(refElement, problems);
}
else {
problems = ArrayUtil.mergeArrays(problems, descriptions);
}
getProblemElements().put(refElement, problems);
for (CommonProblemDescriptor description : descriptions) {
getProblemToElements().put(description, refElement);
collectQuickFixes(description.getFixes(), refElement);
@@ -164,19 +163,22 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
final QuickFix[] fixes = problem.getFixes();
if (isIgnoreProblem(fixes, localQuickFixes, idx)){
getProblemToElements().remove(problem);
CommonProblemDescriptor[] descriptors = getProblemElements().get(refEntity);
if (descriptors != null) {
ArrayList<CommonProblemDescriptor> newDescriptors = new ArrayList<CommonProblemDescriptor>(Arrays.asList(descriptors));
newDescriptors.remove(problem);
getQuickFixActions().put(refEntity, null);
if (!newDescriptors.isEmpty()) {
getProblemElements().put(refEntity, newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()]));
for (CommonProblemDescriptor descriptor : newDescriptors) {
collectQuickFixes(descriptor.getFixes(), refEntity);
Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
synchronized (lock) {
CommonProblemDescriptor[] descriptors = problemElements.get(refEntity);
if (descriptors != null) {
ArrayList<CommonProblemDescriptor> newDescriptors = new ArrayList<CommonProblemDescriptor>(Arrays.asList(descriptors));
newDescriptors.remove(problem);
getQuickFixActions().put(refEntity, null);
if (!newDescriptors.isEmpty()) {
problemElements.put(refEntity, newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()]));
for (CommonProblemDescriptor descriptor : newDescriptors) {
collectQuickFixes(descriptor.getFixes(), refEntity);
}
}
else {
ignoreProblemElement(refEntity);
}
}
else {
ignoreProblemElement(refEntity);
}
}
}
@@ -224,10 +226,13 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
myOldProblemElements = null;
}
myProblemElements = null;
myProblemToElements = null;
myQuickFixActions = null;
myIgnoredElements = null;
synchronized (lock) {
myProblemElements = null;
myProblemToElements = null;
myQuickFixActions = null;
myIgnoredElements = null;
}
myContents = null;
myModulesProblems = null;
}
@@ -261,10 +266,12 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
public void exportResults(@NotNull final Element parentNode) {
getRefManager().iterate(new RefVisitor() {
@Override public void visitElement(final RefEntity refEntity) {
if (getProblemElements().containsKey(refEntity)) {
CommonProblemDescriptor[] descriptions = getDescriptions(refEntity);
if (descriptions != null) {
exportResults(descriptions, refEntity, parentNode);
synchronized (lock) {
if (getProblemElements().containsKey(refEntity)) {
CommonProblemDescriptor[] descriptions = getDescriptions(refEntity);
if (descriptions != null) {
exportResults(descriptions, refEntity, parentNode);
}
}
}
}
@@ -524,10 +531,12 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
}
public Map<RefEntity, CommonProblemDescriptor[]> getProblemElements() {
if (myProblemElements == null) {
myProblemElements = Collections.synchronizedMap(new THashMap<RefEntity, CommonProblemDescriptor[]>());
synchronized (lock) {
if (myProblemElements == null) {
myProblemElements = Collections.synchronizedMap(new THashMap<RefEntity, CommonProblemDescriptor[]>());
}
return myProblemElements;
}
return myProblemElements;
}
@Nullable
@@ -536,23 +545,29 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem
}
private Map<CommonProblemDescriptor, RefEntity> getProblemToElements() {
if (myProblemToElements == null) {
myProblemToElements = Collections.synchronizedMap(new THashMap<CommonProblemDescriptor, RefEntity>());
synchronized (lock) {
if (myProblemToElements == null) {
myProblemToElements = Collections.synchronizedMap(new THashMap<CommonProblemDescriptor, RefEntity>());
}
return myProblemToElements;
}
return myProblemToElements;
}
private Map<RefEntity, Set<QuickFix>> getQuickFixActions() {
if (myQuickFixActions == null) {
myQuickFixActions = Collections.synchronizedMap(new HashMap<RefEntity, Set<QuickFix>>());
synchronized (lock) {
if (myQuickFixActions == null) {
myQuickFixActions = Collections.synchronizedMap(new HashMap<RefEntity, Set<QuickFix>>());
}
return myQuickFixActions;
}
return myQuickFixActions;
}
private Map<RefEntity, CommonProblemDescriptor[]> getIgnoredElements() {
if (myIgnoredElements == null) {
myIgnoredElements = Collections.synchronizedMap(new HashMap<RefEntity, CommonProblemDescriptor[]>());
synchronized (lock) {
if (myIgnoredElements == null) {
myIgnoredElements = Collections.synchronizedMap(new HashMap<RefEntity, CommonProblemDescriptor[]>());
}
return myIgnoredElements;
}
return myIgnoredElements;
}
}
@@ -322,6 +322,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
myBuffer.clear();
myHyperlinks.clearHyperlinks();
}
if (myFlushAlarm.isDisposed()) return;
myFlushAlarm.cancelAllRequests();
myFlushAlarm.addRequest(myClearRequest, 0, getStateForUpdate());
cancelHeavyAlarm();
@@ -20,7 +20,6 @@ import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.project.ProjectUtil;
@@ -111,7 +110,6 @@ public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer>
};
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
private final FileTypeManager myFtManager = FileTypeManager.getInstance();
@Override
public boolean acceptInput(final VirtualFile file) {
if (!(file.getFileSystem() instanceof LocalFileSystem)) {
@@ -25,9 +25,7 @@ import com.android.sdklib.IAndroidTarget;
import com.intellij.android.designer.componentTree.AndroidTreeDecorator;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.componentTree.TreeComponentDecorator;
import com.intellij.designer.designSurface.ComponentDecorator;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.designSurface.selection.DirectionResizePoint;
import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
@@ -193,9 +191,17 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
@Override
protected ComponentDecorator getRootSelectionDecorator() {
return new ResizeSelectionDecorator(Color.RED, 1, new DirectionResizePoint(Position.EAST),
new DirectionResizePoint(Position.SOUTH_EAST),
new DirectionResizePoint(Position.SOUTH));
return new ResizeSelectionDecorator(Color.RED, 1, new DirectionResizePoint(Position.EAST, "top_resize_"),
new DirectionResizePoint(Position.SOUTH_EAST, "top_resize"),
new DirectionResizePoint(Position.SOUTH, "top_resize"));
}
@Override
protected EditOperation processRootOperation(OperationContext context) {
if (context.is("top_resize")) {
return new ResizeOperation(context);
}
return null;
}
private static class RootView extends JComponent {
@@ -0,0 +1,81 @@
/*
* 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.android.designer.designSurface;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.FeedbackLayer;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.designSurface.feedbacks.AlphaComponent;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Position;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class ResizeOperation implements EditOperation {
private final OperationContext myContext;
private RadComponent myComponent;
private JComponent myFeedback;
public ResizeOperation(OperationContext context) {
myContext = context;
}
@Override
public void setComponent(RadComponent component) {
myComponent = component;
}
@Override
public void setComponents(List<RadComponent> component) {
}
@Override
public void showFeedback() {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
if (myFeedback == null) {
myFeedback = new AlphaComponent(Color.GREEN, Color.LIGHT_GRAY);
layer.add(myFeedback);
}
myFeedback.setBounds(myContext.getTransformedRectangle(myComponent.getBounds(layer)));
layer.repaint();
}
@Override
public void eraseFeedback() {
if (myFeedback != null) {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
layer.remove(myFeedback);
layer.repaint();
myFeedback = null;
}
}
@Override
public boolean canExecute() {
return myContext.getResizeDirection() != Position.SOUTH;
}
@Override
public void execute() throws Exception {
}
}
@@ -56,6 +56,11 @@ public class RadViewComponent extends RadComponent {
return myBounds;
}
@Override
public Rectangle getBounds(Component relativeTo) {
return SwingUtilities.convertRectangle(myNativeComponent, myBounds, relativeTo);
}
public void setBounds(int x, int y, int width, int height) {
myBounds.setBounds(x, y, width, height);
}
@@ -68,9 +73,4 @@ public class RadViewComponent extends RadComponent {
public Point convertPoint(Component component, int x, int y) {
return SwingUtilities.convertPoint(component, x, y, myNativeComponent);
}
@Override
public Point convertPoint(int x, int y, Component component) {
return SwingUtilities.convertPoint(myNativeComponent, x, y, component);
}
}
@@ -65,10 +65,4 @@ public class DecorationLayer extends JComponent {
}
return parent.getLayout().getChildSelectionDecorator(component);
}
public Rectangle getComponentBounds(RadComponent component) {
Rectangle bounds = component.getBounds();
Point location = component.convertPoint(bounds.x, bounds.y, this);
return new Rectangle(location.x, location.y, bounds.width, bounds.height);
}
}
@@ -30,6 +30,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -130,6 +131,11 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider
return DesignerEditorPanel.this.getRootSelectionDecorator();
}
@Nullable
public EditOperation processRootOperation(OperationContext context) {
return DesignerEditorPanel.this.processRootOperation(context);
}
@Override
public FeedbackLayer getFeedbackLayer() {
return myFeedbackLayer;
@@ -175,6 +181,9 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider
protected abstract ComponentDecorator getRootSelectionDecorator();
@Nullable
protected abstract EditOperation processRootOperation(OperationContext context);
public InputTool getActiveTool() {
return myTool;
}
@@ -244,6 +253,9 @@ public abstract class DesignerEditorPanel extends JPanel implements ToolProvider
int height = 0;
if (myRootComponent != null) {
width = Math.max(width, (int)myRootComponent.getBounds().getMaxX());
height = Math.max(height, (int)myRootComponent.getBounds().getMaxY());
for (RadComponent component : myRootComponent.getChildren()) {
width = Math.max(width, (int)component.getBounds().getMaxX());
height = Math.max(height, (int)component.getBounds().getMaxY());
@@ -0,0 +1,37 @@
/*
* 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.designer.designSurface;
import com.intellij.designer.model.RadComponent;
import java.util.List;
/**
* @author Alexander Lobas
*/
public interface EditOperation {
void setComponent(RadComponent component);
void setComponents(List<RadComponent> component);
void showFeedback();
void eraseFeedback();
boolean canExecute();
void execute() throws Exception;
}
@@ -92,7 +92,21 @@ public abstract class EditableArea {
public abstract ComponentDecorator getRootSelectionDecorator();
@Nullable
public EditOperation processRootOperation(OperationContext context) {
return null;
}
public abstract FeedbackLayer getFeedbackLayer();
public abstract RadComponent getRootComponent();
public boolean isTree() {
return false;
}
@Nullable
public FeedbackTreeLayer getFeedbackTreeLayer() {
return null;
}
}
@@ -0,0 +1,22 @@
/*
* 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.designer.designSurface;
/**
* @author Alexander Lobas
*/
public interface FeedbackTreeLayer {
}
@@ -0,0 +1,118 @@
/*
* 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.designer.designSurface;
import com.intellij.designer.model.RadComponent;
import java.awt.*;
import java.awt.event.InputEvent;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public final class OperationContext {
private final Object myType;
private EditableArea myArea;
private List<RadComponent> myComponents;
private InputEvent myInputEvent;
private Point myLocation;
private Point myMoveDelta;
private Dimension mySizeDelta;
private int myResizeDirection;
private Object myNewObject;
public OperationContext(Object type) {
myType = type;
}
public Object getType() {
return myType;
}
public boolean is(Object type) {
return type == null ? myType == null : type.equals(myType);
}
public EditableArea getArea() {
return myArea;
}
public void setArea(EditableArea area) {
myArea = area;
}
public List<RadComponent> getComponents() {
return myComponents;
}
public void setComponents(List<RadComponent> components) {
myComponents = components;
}
public InputEvent getInputEvent() {
return myInputEvent;
}
public void setInputEvent(InputEvent inputEvent) {
myInputEvent = inputEvent;
}
public Point getLocation() {
return myLocation;
}
public void setLocation(Point location) {
myLocation = location;
}
public Point getMoveDelta() {
return myMoveDelta;
}
public void setMoveDelta(Point moveDelta) {
myMoveDelta = moveDelta;
}
public Dimension getSizeDelta() {
return mySizeDelta;
}
public void setSizeDelta(Dimension sizeDelta) {
mySizeDelta = sizeDelta;
}
public Rectangle getTransformedRectangle(Rectangle r) {
return new Rectangle(r.x + myMoveDelta.x, r.y + myMoveDelta.y, r.width + mySizeDelta.width, r.height + mySizeDelta.height);
}
public int getResizeDirection() {
return myResizeDirection;
}
public void setResizeDirection(int resizeDirection) {
myResizeDirection = resizeDirection;
}
public Object getNewObject() {
return myNewObject;
}
public void setNewObject(Object newObject) {
myNewObject = newObject;
}
}
@@ -0,0 +1,57 @@
/*
* 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.designer.designSurface.feedbacks;
import javax.swing.*;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public class AlphaComponent extends JComponent {
private static final AlphaComposite myComposite1 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f);
private static final AlphaComposite myComposite2 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.6f);
private final Color myColor;
private final Color myBorderColor;
public AlphaComponent(Color color) {
this(color, color);
}
public AlphaComponent(Color color, Color borderColor) {
myColor = color;
myBorderColor = borderColor;
}
protected void paintComponent(final Graphics g) {
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g);
final Composite oldComposite = g2d.getComposite();
final Color oldColor = g2d.getColor();
g2d.setColor(myColor);
g2d.setComposite(myComposite1);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(myBorderColor);
g2d.setComposite(myComposite2);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.setColor(oldColor);
g2d.setComposite(oldComposite);
}
}
@@ -28,16 +28,19 @@ import java.awt.*;
*/
public class DirectionResizePoint extends ResizePoint {
private int myDirection;
private Object myType;
private double myXSeparator;
private double myYSeparator;
public DirectionResizePoint(int direction) {
public DirectionResizePoint(int direction, Object type) {
setDirection(direction);
myType = type;
}
public DirectionResizePoint(Color color, Color border, int direction) {
public DirectionResizePoint(Color color, Color border, int direction, Object type) {
super(color, border);
setDirection(direction);
myType = type;
}
private void setDirection(int direction) {
@@ -68,12 +71,12 @@ public class DirectionResizePoint extends ResizePoint {
@Override
protected InputTool createTool(RadComponent component) {
return new ResizeTracker(myDirection);
return new ResizeTracker(myDirection, myType);
}
@Override
protected Point getLocation(DecorationLayer layer, RadComponent component) {
Rectangle bounds = layer.getComponentBounds(component);
Rectangle bounds = component.getBounds(layer);
int size = (getSize() + 1) / 2;
int x = bounds.x + (int) (bounds.width * myXSeparator) - size;
int y = bounds.y + (int) (bounds.height * myYSeparator) - size;
@@ -17,7 +17,6 @@ package com.intellij.designer.designSurface.selection;
import com.intellij.designer.designSurface.ComponentDecorator;
import com.intellij.designer.designSurface.DecorationLayer;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.designSurface.tools.DragTracker;
import com.intellij.designer.designSurface.tools.InputTool;
import com.intellij.designer.model.RadComponent;
@@ -38,7 +37,7 @@ public class NonResizeSelectionDecorator implements ComponentDecorator {
@Override
public InputTool findTargetTool(DecorationLayer layer, RadComponent component, int x, int y) {
Rectangle bounds = layer.getComponentBounds(component);
Rectangle bounds = component.getBounds(layer);
int lineWidth = Math.max(myLineWidth, 2);
Rectangle top = new Rectangle(bounds.x, bounds.y, bounds.width, lineWidth);
@@ -60,7 +59,7 @@ public class NonResizeSelectionDecorator implements ComponentDecorator {
g.setStroke(new BasicStroke(myLineWidth));
}
Rectangle bounds = layer.getComponentBounds(component);
Rectangle bounds = component.getBounds(layer);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
@@ -18,13 +18,22 @@ package com.intellij.designer.designSurface.tools;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Cursors;
import java.awt.*;
/**
* @author Alexander Lobas
*/
public class DragTracker extends SelectionTracker {
private static final Cursor myDragCursor = Cursors.getMoveCursor();
public DragTracker(RadComponent component) {
super(component);
setDefaultCursor(Cursors.RESIZE_ALL);
setDisabledCursor(Cursors.getNoCursor());
}
@Override
protected Cursor getDefaultCursor() {
return myState == STATE_NONE ? super.getDefaultCursor() : myDragCursor;
}
}
@@ -37,7 +37,7 @@ public abstract class InputTool {
protected ToolProvider myToolProvider;
protected EditableArea myArea;
private Object myCommand;
protected Object myCommand;
private boolean myActive;
private boolean myCanUnload = true;
@@ -100,10 +100,6 @@ public abstract class InputTool {
}
}
protected final boolean unloadWhenFinished() {
return myCanUnload;
}
public final void setUnloadWhenFinished(boolean value) {
myCanUnload = value;
}
@@ -144,7 +140,7 @@ public abstract class InputTool {
return getDefaultCursor();
}
protected final Cursor getDefaultCursor() {
protected Cursor getDefaultCursor() {
return myDefaultCursor;
}
@@ -228,7 +224,7 @@ public abstract class InputTool {
protected void handleAreaExited() {
}
protected void handleFinished() {
protected final void handleFinished() {
if (myCanUnload) {
myToolProvider.loadDefaultTool();
}
@@ -18,6 +18,7 @@ package com.intellij.designer.designSurface.tools;
import com.intellij.designer.designSurface.FeedbackLayer;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadComponentVisitor;
import com.intellij.designer.designSurface.feedbacks.AlphaComponent;
import com.intellij.designer.utils.Cursors;
import javax.swing.*;
@@ -30,8 +31,6 @@ import java.util.List;
* @author Alexander Lobas
*/
public class MarqueeTracker extends InputTool {
private static final AlphaComposite myComposite1 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f);
private static final AlphaComposite myComposite2 = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.6f);
private static final Color myColor = new Color(47, 67, 96);
private static final int TOGGLE_MODE = 1;
@@ -111,24 +110,7 @@ public class MarqueeTracker extends InputTool {
FeedbackLayer layer = myArea.getFeedbackLayer();
if (myFeedback == null) {
myFeedback = new JComponent() {
protected void paintComponent(final Graphics g) {
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g);
final Composite oldComposite = g2d.getComposite();
final Color oldColor = g2d.getColor();
g2d.setColor(myColor);
g2d.setComposite(myComposite1);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(myComposite2);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.setColor(oldColor);
g2d.setComposite(oldComposite);
}
};
myFeedback = new AlphaComponent(myColor);
layer.add(myFeedback);
}
@@ -156,11 +138,7 @@ public class MarqueeTracker extends InputTool {
myArea.getRootComponent().accept(new RadComponentVisitor() {
@Override
public void endVisit(RadComponent component) {
Rectangle bounds = component.getBounds();
Point location = component.convertPoint(bounds.x, bounds.y, myArea.getNativeComponent());
if (selectionRectangle.contains(location) &&
selectionRectangle.contains(location.x + bounds.width, location.y + bounds.height)) {
if (selectionRectangle.contains(component.getBounds(myArea.getNativeComponent()))) {
newSelection.add(component);
}
}
@@ -15,13 +15,180 @@
*/
package com.intellij.designer.designSurface.tools;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Cursors;
import com.intellij.designer.utils.Position;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class ResizeTracker extends InputTool {
public ResizeTracker(int direction) {
private OperationContext myContext;
private List<EditOperation> myOperations;
private boolean myShowFeedback;
private final int myDirection;
public ResizeTracker(int direction, Object type) {
myDirection = direction;
myContext = new OperationContext(type);
myContext.setResizeDirection(direction);
setDefaultCursor(Cursors.getResizeCursor(direction));
setDisabledCursor(Cursors.getNoCursor());
}
@Override
public void deactivate() {
eraseFeedback();
myContext = null;
myOperations = null;
super.deactivate();
}
@Override
protected Cursor calculateCursor() {
if (myState == STATE_DRAG) {
return getDefaultCursor();
}
return super.calculateCursor();
}
@Override
protected void handleButtonDown(int button) {
if (button == 1) {
if (myState == STATE_INIT) {
myState = STATE_DRAG;
}
}
else {
myState = STATE_INVALID;
eraseFeedback();
setCommand(null);
}
}
@Override
protected void handleButtonUp(int button) {
if (myState == STATE_DRAG_IN_PROGRESS) {
myState = STATE_NONE;
eraseFeedback();
executeCommand();
}
}
@Override
protected void handleDragStarted() {
if (myState == STATE_DRAG) {
myState = STATE_DRAG_IN_PROGRESS;
}
}
@Override
protected void handleDragInProgress() {
if (myState == STATE_DRAG_IN_PROGRESS) {
updateContext();
showFeedback();
setCommand();
}
}
private void showFeedback() {
for (EditOperation operation : getOperations()) {
operation.showFeedback();
}
myShowFeedback = true;
}
private void eraseFeedback() {
if (myShowFeedback) {
myShowFeedback = false;
for (EditOperation operation : getOperations()) {
operation.eraseFeedback();
}
}
}
private void executeCommand() {
if (myCommand != null) {
try {
for (EditOperation operation : getOperations()) {
if (operation.canExecute()) {
operation.execute();
}
}
}
catch (Exception e) {
myToolProvider.showError("Execute command: ", e);
}
}
}
private void setCommand() {
for (EditOperation operation : getOperations()) {
if (operation.canExecute()) {
setCommand(this);
return;
}
}
setCommand(null);
}
private void updateContext() {
myContext.setArea(myArea);
myContext.setInputEvent(myInputEvent);
Point corner = new Point();
Dimension resize = new Dimension();
int moveDeltaHeight = myCurrentScreenY - myStartScreenY;
if ((myDirection & Position.NORTH) != 0) {
corner.y += moveDeltaHeight;
resize.height -= moveDeltaHeight;
}
else if ((myDirection & Position.SOUTH) != 0) {
resize.height += moveDeltaHeight;
}
int moveDeltaWidth = myCurrentScreenX - myStartScreenX;
if ((myDirection & Position.WEST) != 0) {
corner.x += moveDeltaWidth;
resize.width -= moveDeltaWidth;
}
else if ((myDirection & Position.EAST) != 0) {
resize.width += moveDeltaWidth;
}
myContext.setMoveDelta(corner);
myContext.setSizeDelta(resize);
myContext.setLocation(new Point(myCurrentScreenX, myCurrentScreenY));
}
private List<EditOperation> getOperations() {
if (myOperations == null) {
myContext.setComponents(new ArrayList<RadComponent>(myArea.getSelection()));
myOperations = new ArrayList<EditOperation>();
for (RadComponent component : myContext.getComponents()) {
EditOperation operation;
RadComponent parent = component.getParent();
if (parent == null) {
operation = myArea.processRootOperation(myContext);
}
else {
operation = parent.getLayout().processChildOperation(myContext);
}
if (operation != null) {
myOperations.add(operation);
operation.setComponent(component);
}
}
}
return myOperations;
}
}
@@ -32,26 +32,43 @@ import java.util.List;
public class SelectionTool extends InputTool {
private InputTool myTracker;
@Override
public void deactivate() {
deactivateTracker();
super.deactivate();
}
@Override
public void refreshCursor() {
if (myTracker == null) {
super.refreshCursor();
}
}
@Override
protected void handleButtonDown(int button) {
if (myState == STATE_INIT) {
myState = STATE_DRAG;
deactivateTracker();
if (myInputEvent.isAltDown()) {
setTracker(new MarqueeTracker());
return;
}
if (!myArea.isTree()) {
if (myInputEvent.isAltDown()) {
setTracker(new MarqueeTracker());
return;
}
InputTool tracker = myArea.findTargetTool(myCurrentScreenX, myCurrentScreenY);
if (tracker != null) {
setTracker(tracker);
return;
InputTool tracker = myArea.findTargetTool(myCurrentScreenX, myCurrentScreenY);
if (tracker != null) {
setTracker(tracker);
return;
}
}
RadComponent component = myArea.findTarget(myCurrentScreenX, myCurrentScreenY);
if (component == null) {
setTracker(new MarqueeTracker());
if (!myArea.isTree()) {
setTracker(new MarqueeTracker());
}
}
else {
setTracker(component.getDragTracker());
@@ -78,19 +95,6 @@ public class SelectionTool extends InputTool {
}
}
@Override
public void deactivate() {
deactivateTracker();
super.deactivate();
}
@Override
public void refreshCursor() {
if (myTracker == null) {
super.refreshCursor();
}
}
private void setTracker(@Nullable InputTool tracker) {
if (myTracker != tracker) {
deactivateTracker();
@@ -36,6 +36,12 @@ public abstract class RadComponent {
private RadLayout myLayout;
private final Map<Object, Object> myClientProperties = new HashMap<Object, Object>();
//////////////////////////////////////////////////////////////////////////////////////////
//
// Hierarchy
//
//////////////////////////////////////////////////////////////////////////////////////////
public RadComponent getRoot() {
return myParent == null ? this : myParent.getRoot();
}
@@ -56,15 +62,21 @@ public abstract class RadComponent {
return getChildren().toArray();
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Visual
//
//////////////////////////////////////////////////////////////////////////////////////////
public Rectangle getBounds() {
return null;
}
public Point convertPoint(Component component, int x, int y) {
public Rectangle getBounds(Component relativeTo) {
return null;
}
public Point convertPoint(int x, int y, Component component) {
public Point convertPoint(Component relativeFrom, int x, int y) {
return null;
}
@@ -72,6 +84,12 @@ public abstract class RadComponent {
return new DragTracker(this);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// layout
//
//////////////////////////////////////////////////////////////////////////////////////////
public RadLayout getLayout() {
return myLayout;
}
@@ -85,6 +103,12 @@ public abstract class RadComponent {
return null;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Properties
//
//////////////////////////////////////////////////////////////////////////////////////////
public List<Property> getProperties() {
return null;
}
@@ -97,6 +121,12 @@ public abstract class RadComponent {
myClientProperties.put(key, value);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Visitor
//
//////////////////////////////////////////////////////////////////////////////////////////
public void accept(RadComponentVisitor visitor, boolean forward) {
if (visitor.visit(this)) {
List<RadComponent> children = getChildren();
@@ -16,10 +16,18 @@
package com.intellij.designer.model;
import com.intellij.designer.designSurface.ComponentDecorator;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.OperationContext;
import org.jetbrains.annotations.Nullable;
/**
* @author Alexander Lobas
*/
public abstract class RadLayout {
public abstract ComponentDecorator getChildSelectionDecorator(RadComponent component);
@Nullable
public EditOperation processChildOperation(OperationContext context) {
return null;
}
}
@@ -35,6 +35,26 @@ public final class Cursors {
}
}
// TODO: replace on better cursor (self image)
public static Cursor getMoveCursor() {
try {
return Cursor.getSystemCustomCursor("MoveDrop.32x32");
}
catch (Exception ex) {
return Cursor.getDefaultCursor();
}
}
// TODO: replace on better cursor (self image)
public static Cursor getCopyCursor() {
try {
return Cursor.getSystemCustomCursor("CopyDrop.32x32");
}
catch (Exception ex) {
return Cursor.getDefaultCursor();
}
}
@Nullable
public static Cursor getResizeCursor(int direction) {
int cursor;
@@ -124,11 +124,12 @@ class XsContentDFA extends XmlContentDFA {
}
private static QName createQName(XmlTag tag) {
//todo don't use intern to not pollute PermGen
String namespace = tag.getNamespace();
return new QName(tag.getNamespacePrefix(),
tag.getLocalName(),
tag.getName(),
namespace.length() == 0 ? null : namespace);
return new QName(tag.getNamespacePrefix().intern(),
tag.getLocalName().intern(),
tag.getName().intern(),
namespace.length() == 0 ? null : namespace.intern());
}
@Nullable