Merge remote-tracking branch 'origin/master'

This commit is contained in:
Kirill Likhodedov
2011-09-28 18:13:01 +04:00
116 changed files with 6799 additions and 6157 deletions
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompilerConfigurable">
<grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="79" y="160" width="529" height="191"/>
<xy x="79" y="160" width="529" height="210"/>
</constraints>
<properties/>
<clientProperties>
@@ -80,9 +80,17 @@
<margin top="0" left="2" bottom="0" right="0"/>
<text value="128"/>
</properties>
<clientProperties>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
</children>
</grid>
<vspacer id="af30">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable">
<grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="79" y="160" width="529" height="205"/>
<xy x="79" y="160" width="529" height="210"/>
</constraints>
<properties/>
<clientProperties>
@@ -79,9 +79,17 @@
<margin top="0" left="2" bottom="0" right="0"/>
<text value="128"/>
</properties>
<clientProperties>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
</children>
</grid>
<vspacer id="72a3c">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2011 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.compiler.options;
import com.intellij.compiler.CompilerConfiguration;
@@ -197,7 +212,7 @@ public class AnnotationProcessorsConfigurable implements SearchableConfigurable
if (header != null) {
header.repaint();
}
myModulesTable.setEnabled(enabled);
myModulesTable.getComponent().setEnabled(enabled);
}
public boolean isModified() {
@@ -254,7 +254,7 @@ public class SourcePathsStep extends AbstractStepWithProgress<List<Trinity<Strin
final String sourceDirectoryPath = getSourceDirectoryPath();
final String relativePath = myTfSourceDirectoryName.getText().trim();
if (relativePath.length() == 0) {
String text = IdeBundle.message("prompt.relative.path.to.sources.empty", sourceDirectoryPath);
String text = IdeBundle.message("prompt.relative.path.to.sources.empty", FileUtil.toSystemDependentName(sourceDirectoryPath));
final int answer = Messages.showYesNoCancelDialog(myTfSourceDirectoryName, text, IdeBundle.message("title.mark.source.directory"),
IdeBundle.message("action.mark"), IdeBundle.message("action.do.not.mark"),
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon());
@@ -62,7 +62,7 @@ import java.util.Set;
public class SdkEditor implements Configurable, Place.Navigator {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.ui.SdkEditor");
private Sdk mySdk;
private final Map<OrderRootType, PathEditor> myPathEditors = new HashMap<OrderRootType, PathEditor>();
private final Map<OrderRootType, SdkPathEditor> myPathEditors = new HashMap<OrderRootType, SdkPathEditor>();
private TextFieldWithBrowseButton myHomeComponent;
private final Map<SdkType, AdditionalDataConfigurable> myAdditionalDataConfigurables = new HashMap<SdkType, AdditionalDataConfigurable>();
@@ -131,7 +131,7 @@ public class SdkEditor implements Configurable, Place.Navigator {
myTabbedPane = new TabbedPaneWrapper(myDisposable);
for (OrderRootType type : OrderRootType.getAllTypes()) {
if (mySdk == null || showTabForType(type)) {
final PathEditor pathEditor = OrderRootTypeUIFactory.FACTORY.getByKey(type).createPathEditor(mySdk);
final SdkPathEditor pathEditor = OrderRootTypeUIFactory.FACTORY.getByKey(type).createPathEditor(mySdk);
if (pathEditor != null) {
myTabbedPane.addTab(pathEditor.getDisplayName(), pathEditor.createComponent());
myPathEditors.put(type, pathEditor);
@@ -201,7 +201,7 @@ public class SdkEditor implements Configurable, Place.Navigator {
myInitialPath = mySdk.getHomePath();
final SdkModificator sdkModificator = mySdk.getSdkModificator();
sdkModificator.setHomePath(getHomeValue().replace(File.separatorChar, '/'));
for (PathEditor pathEditor : myPathEditors.values()) {
for (SdkPathEditor pathEditor : myPathEditors.values()) {
pathEditor.apply(sdkModificator);
}
ApplicationManager.getApplication().runWriteAction(new Runnable() { // fix SCR #29193
@@ -219,7 +219,7 @@ public class SdkEditor implements Configurable, Place.Navigator {
public void reset(){
if (mySdk == null){
setHomePathValue("");
for (PathEditor pathEditor : myPathEditors.values()) {
for (SdkPathEditor pathEditor : myPathEditors.values()) {
pathEditor.reset(null);
}
}
@@ -23,7 +23,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.AnnotationOrderRootType;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.util.IconLoader;
@@ -43,8 +43,8 @@ public class AnnotationsOrderRootTypeUIFactory implements OrderRootTypeUIFactory
return ProjectBundle.message("sdk.configure.annotations.tab");
}
public PathEditor createPathEditor(Sdk sdk) {
return new PathEditor(ProjectBundle.message("sdk.configure.annotations.tab"), AnnotationOrderRootType.getInstance(),
public SdkPathEditor createPathEditor(Sdk sdk) {
return new SdkPathEditor(ProjectBundle.message("sdk.configure.annotations.tab"), AnnotationOrderRootType.getInstance(),
FileChooserDescriptorFactory.createSingleFolderDescriptor());
}
}
@@ -23,7 +23,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.util.IconLoader;
@@ -33,8 +33,8 @@ import javax.swing.*;
public class ClassesOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
private static final Icon ICON = IconLoader.getIcon("/nodes/compiledClassesFolder.png");
public PathEditor createPathEditor(Sdk sdk) {
return new PathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, new FileChooserDescriptor(true, true, true, false, true, true));
public SdkPathEditor createPathEditor(Sdk sdk) {
return new SdkPathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, new FileChooserDescriptor(true, true, true, false, true, true));
}
@Override
@@ -28,6 +28,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryType;
import com.intellij.openapi.roots.libraries.ui.LibraryRootsComponentDescriptor;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.libraries.ui.RootDetector;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
import com.intellij.openapi.roots.ui.configuration.projectRoot.BaseLibrariesConfigurable;
@@ -72,17 +73,25 @@ public class CreateNewLibraryAction extends DumbAwareAction {
if (componentDescriptor == null) {
componentDescriptor = new DefaultLibraryRootsComponentDescriptor();
}
final FileChooserDescriptor chooserDescriptor = componentDescriptor.createAttachFilesChooserDescriptor();
chooserDescriptor.setTitle("Select Library Files");
final VirtualFile[] rootCandidates = FileChooser.chooseFiles(myLibrariesConfigurable.getTree(), chooserDescriptor, myProject.getBaseDir());
if (rootCandidates.length == 0) {
return;
}
final List<? extends RootDetector> rootDetectors = componentDescriptor.getRootDetectors();
final List<OrderRoot> roots;
if (!rootDetectors.isEmpty()) {
final FileChooserDescriptor chooserDescriptor = componentDescriptor.createAttachFilesChooserDescriptor();
chooserDescriptor.setTitle("Select Library Files");
final VirtualFile[] rootCandidates = FileChooser.chooseFiles(myLibrariesConfigurable.getTree(), chooserDescriptor,
myProject.getBaseDir());
if (rootCandidates.length == 0) {
return;
}
final List<OrderRoot> roots = RootDetectionUtil
.detectRoots(Arrays.asList(rootCandidates), myLibrariesConfigurable.getTree(), myProject, componentDescriptor.getRootDetectors(),
true);
if (roots.isEmpty()) return;
roots = RootDetectionUtil
.detectRoots(Arrays.asList(rootCandidates), myLibrariesConfigurable.getTree(), myProject, rootDetectors,
true);
if (roots.isEmpty()) return;
}
else {
roots = Collections.emptyList();
}
final LibrariesModifiableModel modifiableModel = myLibrariesConfigurable.getModelProvider().getModifiableModel();
final Library library = modifiableModel.createLibrary(LibraryEditingUtil.suggestNewLibraryName(modifiableModel, roots), myType);
@@ -20,13 +20,12 @@
*/
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.projectRoots.ui.Util;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
@@ -38,7 +37,7 @@ import javax.swing.*;
public class JavadocOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
private static final Icon ICON = IconLoader.getIcon("/nodes/javaDocFolder.png");
public PathEditor createPathEditor(Sdk sdk) {
public SdkPathEditor createPathEditor(Sdk sdk) {
return new JavadocPathsEditor(sdk);
}
@@ -52,7 +51,7 @@ public class JavadocOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
return ProjectBundle.message("library.javadocs.node");
}
static class JavadocPathsEditor extends PathEditor {
static class JavadocPathsEditor extends SdkPathEditor {
private final Sdk mySdk;
public JavadocPathsEditor(Sdk sdk) {
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
@@ -37,6 +38,8 @@ import java.util.List;
* @author nik
*/
public class RootDetectionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.libraryEditor.RootDetectionUtil");
private RootDetectionUtil() {
}
@@ -45,6 +48,7 @@ public class RootDetectionUtil {
@Nullable Project project,
@NotNull final List<? extends RootDetector> detectors,
boolean allowUserToSelectRootTypeIfNothingIsDetected) {
LOG.assertTrue(!detectors.isEmpty());
final List<OrderRoot> result = new ArrayList<OrderRoot>();
final List<SuggestedChildRootInfo> suggestedRoots = new ArrayList<SuggestedChildRootInfo>();
new Task.Modal(project, "Scanning for Roots", true) {
@@ -69,14 +73,15 @@ public class RootDetectionUtil {
if (!suggestedRoots.isEmpty()) {
final DetectedRootsChooserDialog dialog = parentComponent != null
? new DetectedRootsChooserDialog(parentComponent, suggestedRoots)
: new DetectedRootsChooserDialog(project, suggestedRoots);
? new DetectedRootsChooserDialog(parentComponent, suggestedRoots)
: new DetectedRootsChooserDialog(project, suggestedRoots);
dialog.show();
if (!dialog.isOK()) {
return Collections.emptyList();
}
for (SuggestedChildRootInfo rootInfo : dialog.getChosenRoots()) {
result.add(new OrderRoot(rootInfo.getSuggestedRoot(), rootInfo.getDetector().getRootType(), rootInfo.getDetector().isJarDirectory()));
result
.add(new OrderRoot(rootInfo.getSuggestedRoot(), rootInfo.getDetector().getRootType(), rootInfo.getDetector().isJarDirectory()));
}
}
@@ -86,7 +91,7 @@ public class RootDetectionUtil {
names.add(detector.getPresentableRootTypeName());
}
final int i = Messages.showChooseDialog("Choose category for selected files:", "Attach Files",
ArrayUtil.toStringArray(names), names.get(0), null);
ArrayUtil.toStringArray(names), names.get(0), null);
if (i != -1) {
final RootDetector detector = detectors.get(i);
for (VirtualFile candidate : rootCandidates) {
@@ -23,9 +23,9 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.roots.ui.configuration.PathUIUtils;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
@@ -36,8 +36,8 @@ import java.awt.*;
public class SourcesOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
private static final Icon ICON = IconLoader.getIcon("/nodes/sourceFolder.png");
public PathEditor createPathEditor(Sdk sdk) {
return new PathEditor(ProjectBundle.message("sdk.configure.sourcepath.tab"), OrderRootType.SOURCES, new FileChooserDescriptor(true, true, true, false, true, true)) {
public SdkPathEditor createPathEditor(Sdk sdk) {
return new SdkPathEditor(ProjectBundle.message("sdk.configure.sourcepath.tab"), OrderRootType.SOURCES, new FileChooserDescriptor(true, true, true, false, true, true)) {
@Override
protected VirtualFile[] adjustAddedFileSet(final Component component, final VirtualFile[] files) {
return PathUIUtils.scanAndSelectDetectedJavaSourceRoots(component, files);
@@ -26,6 +26,7 @@ import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.filters.*;
import com.intellij.psi.filters.classes.EnumOrAnnotationTypeFilter;
@@ -38,6 +39,7 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspClassLevelDeclarationStatemen
import com.intellij.psi.jsp.JspElementType;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NonNls;
@@ -441,9 +443,12 @@ public class JavaCompletionData extends JavaAwareCompletionData{
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.TRY), TailType.createSimpleTailType('{')));
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.THROW), TailType.SPACE));
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), TailType.SPACE));
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.ASSERT), TailType.SPACE));
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.SYNCHRONIZED), TailTypes.SYNCHRONIZED_LPARENTH));
if (PsiUtil.getLanguageLevel(position).isAtLeast(LanguageLevel.JDK_1_4)) {
variant.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.ASSERT), TailType.SPACE));
}
TailType returnTail = getReturnTail(position);
LookupElement ret = createKeyword(position, PsiKeyword.RETURN);
if (returnTail != TailType.NONE) {
@@ -27,6 +27,7 @@ import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -55,13 +56,7 @@ public class MoveClassToSeparateFileFix implements IntentionAction {
PsiDirectory dir = file.getContainingDirectory();
if (dir == null) return false;
try {
String name = myClass.getName();
if (myClass.isInterface()) {
JavaDirectoryService.getInstance().checkCreateInterface(dir, name);
}
else {
JavaDirectoryService.getInstance().checkCreateClass(dir, name);
}
JavaDirectoryServiceImpl.checkCreateClassOrInterface(dir, myClass.getName());
}
catch (IncorrectOperationException e) {
return false;
@@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NonNls;
@@ -103,8 +104,8 @@ public abstract class JavaCodeContextType extends TemplateContextType {
return false;
}
PsiElement parent = element.getParent().getParent();
return parent instanceof PsiExpressionStatement || parent instanceof PsiTypeElement && parent.getParent() instanceof PsiVariable;
PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
return statement != null && statement.getTextRange().getStartOffset() == element.getTextRange().getStartOffset();
}
}
public static class Expression extends JavaCodeContextType {
@@ -1434,7 +1434,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
if (dfaValue instanceof DfaVariableValue) {
DfaVariableValue dfaVariable = (DfaVariableValue)dfaValue;
PsiVariable psiVariable = dfaVariable.getPsiVariable();
if (psiVariable instanceof PsiField && !psiVariable.hasModifierProperty(PsiModifier.FINAL)) {
if (psiVariable instanceof PsiField) {
addField(dfaVariable);
}
}
@@ -286,6 +286,7 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
PsiField field = (PsiField)resolved;
if (!field.hasModifierProperty(PsiModifier.FINAL)) return false;
if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
PsiElement parent = element.getParent();
if (parent instanceof PsiPrefixExpression && ((PsiPrefixExpression)parent).getOperationTokenType() == JavaTokenType.EXCL) {
@@ -229,7 +229,9 @@ public class DataFlowRunner {
@Override
public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
if (myNewExpression == instruction.getCallExpression()) {
myClosureStates.add(memState.createCopy());
DfaMemoryState copy = memState.createCopy();
copy.flushFields(runner);
myClosureStates.add(copy);
}
return super.visitMethodCall(instruction, runner, memState);
}
@@ -28,6 +28,7 @@ import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.util.TypeConversionUtil;
@@ -678,6 +679,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
public void flushVariable(@NotNull DfaVariableValue variable) {
if (variable.getPsiVariable().hasModifierProperty(PsiModifier.FINAL)) {
return;
}
final int id = variable.getID();
int size = myEqClasses.size();
int interruptCount = 0;
@@ -78,7 +78,7 @@ public class DfaValueFactory {
PsiExpression initializer = variable.getInitializer();
if (initializer instanceof PsiPolyadicExpression && variable.hasModifierProperty(PsiModifier.FINAL)) {
PsiType type = initializer.getType();
if (type != null && type.equalsToText("java.lang.String")) {
if (type != null && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
return getNotNullFactory().create(type);
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.util.IncorrectOperationException;
import java.util.Properties;
@@ -50,13 +51,7 @@ public class JavaCreateFromTemplateHandler implements CreateFromTemplateHandler
CodeStyleManager.getInstance(project).reformat(psiJavaFile);
}
String className = createdClass.getName();
String fileName = className + "." + extension;
if(createdClass.isInterface()){
JavaDirectoryService.getInstance().checkCreateInterface(directory, className);
}
else{
JavaDirectoryService.getInstance().checkCreateClass(directory, className);
}
JavaDirectoryServiceImpl.checkCreateClassOrInterface(directory, className);
final LanguageLevel ll = JavaDirectoryService.getInstance().getLanguageLevel(directory);
if (ll.compareTo(LanguageLevel.JDK_1_5) < 0) {
@@ -69,7 +64,7 @@ public class JavaCreateFromTemplateHandler implements CreateFromTemplateHandler
}
}
psiJavaFile = (PsiJavaFile)psiJavaFile.setName(fileName);
psiJavaFile = (PsiJavaFile)psiJavaFile.setName(className + "." + extension);
PsiElement addedElement = directory.add(psiJavaFile);
if (addedElement instanceof PsiJavaFile) {
psiJavaFile = (PsiJavaFile)addedElement;
@@ -74,10 +74,10 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return generateClassInfo((PsiClass)element);
}
else if (element instanceof PsiMethod) {
return generateMethodInfo((PsiMethod)element);
return generateMethodInfo((PsiMethod)element, calcSubstitutor(originalElement));
}
else if (element instanceof PsiField) {
return generateFieldInfo((PsiField)element);
return generateFieldInfo((PsiField)element, calcSubstitutor(originalElement));
}
else if (element instanceof PsiVariable) {
return generateVariableInfo((PsiVariable)element);
@@ -86,11 +86,19 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return generatePackageInfo((PsiPackage)element);
}
else if (element instanceof BeanPropertyElement) {
return generateMethodInfo(((BeanPropertyElement) element).getMethod());
return generateMethodInfo(((BeanPropertyElement) element).getMethod(), PsiSubstitutor.EMPTY);
}
return null;
}
private static PsiSubstitutor calcSubstitutor(PsiElement originalElement) {
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
if (originalElement instanceof PsiReferenceExpression) {
substitutor = ((PsiReferenceExpression)originalElement).advancedResolve(true).getSubstitutor();
}
return substitutor;
}
public List<String> getUrlFor(final PsiElement element, final PsiElement originalElement) {
return getExternalJavaDocUrl(element);
}
@@ -245,7 +253,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
}
@SuppressWarnings({"HardCodedStringLiteral"})
public static String generateMethodInfo(PsiMethod method) {
public static String generateMethodInfo(PsiMethod method, PsiSubstitutor substitutor) {
StringBuilder buffer = new StringBuilder();
PsiClass parentClass = method.getContainingClass();
@@ -288,7 +296,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
}
if (method.getReturnType() != null) {
JavaDocInfoGenerator.generateType(buffer, method.getReturnType(), method, false);
JavaDocInfoGenerator.generateType(buffer, substitutor.substitute(method.getReturnType()), method, false);
buffer.append(" ");
}
@@ -298,7 +306,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
PsiParameter[] parms = method.getParameterList().getParameters();
for (int i = 0; i < parms.length; i++) {
PsiParameter parm = parms[i];
JavaDocInfoGenerator.generateType(buffer, parm.getType(), method, false);
JavaDocInfoGenerator.generateType(buffer, substitutor.substitute(parm.getType()), method, false);
buffer.append(" ");
if (parm.getName() != null) {
buffer.append(parm.getName());
@@ -333,7 +341,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return buffer.toString();
}
private static String generateFieldInfo(PsiField field) {
private static String generateFieldInfo(PsiField field, PsiSubstitutor substitutor) {
StringBuilder buffer = new StringBuilder();
PsiClass parentClass = field.getContainingClass();
@@ -344,7 +352,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
generateModifiers(buffer, field);
JavaDocInfoGenerator.generateType(buffer, field.getType(), field, false);
JavaDocInfoGenerator.generateType(buffer, substitutor.substitute(field.getType()), field, false);
buffer.append(" ");
buffer.append(field.getName());
@@ -170,13 +170,6 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService {
checkCreateClassOrInterface(dir, name);
}
public void checkCreateInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
checkCreateClassOrInterface(dir, name);
}
/**
* @not_implemented
*/
public static void checkCreateClassOrInterface(@NotNull PsiDirectory directory, String name) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(directory.getManager(), name);
@@ -63,6 +63,7 @@ import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -243,13 +244,19 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
}
return len;
}
private int getTypesColumnWidth() {
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
font = new Font(font.getFontName(), font.getStyle(), 12);
return (getTypesMaxLength() + 1)* Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W");
}
@Override
protected JBTableRowEditor getTableEditor(final JTable t, final ParameterTableModelItemBase<ParameterInfoImpl> item) {
return new JBTableRowEditor() {
private EditorTextField myTypeEditor;
private EditorTextField myNameEditor;
private EditorTextField myDefaultValueEditor;
private EditorTextField myDefaultValueEditor;
private JCheckBox myAnyVar;
@Override
@@ -321,7 +328,11 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
@Override
public JComponent getPreferredFocusedComponent() {
return myTypeEditor;
final MouseEvent me = getMouseEvent();
if (me == null) {
return myTypeEditor;
}
return me.getPoint().getX() <= getTypesColumnWidth() ? myTypeEditor : myNameEditor;
}
@Override
@@ -29,6 +29,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.module.Module;
@@ -81,7 +83,7 @@ public class CreateTestDialog extends DialogWrapper {
private final List<JRadioButton> myLibraryButtons = new ArrayList<JRadioButton>();
private ComboBox myLanguageCombo;
private JTextField myTargetClassNameField;
private EditorTextField myTargetClassNameField;
private ReferenceEditorWithBrowseButton mySuperClassField;
private ReferenceEditorComboWithBrowseButton myTargetPackageField;
private JCheckBox myGenerateBeforeBox;
@@ -181,10 +183,10 @@ public class CreateTestDialog extends DialogWrapper {
}
}
myTargetClassNameField = new JTextField(targetClass.getName() + "Test");
setPreferredSize(myTargetClassNameField);
myTargetClassNameField = new EditorTextField(targetClass.getName() + "Test");
myTargetClassNameField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
@Override
public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) {
getOKAction().setEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getClassName()));
}
});
@@ -227,13 +229,6 @@ public class CreateTestDialog extends DialogWrapper {
mySelectedFramework = descriptor;
}
private void setPreferredSize(JTextField field) {
Dimension size = field.getPreferredSize();
FontMetrics fontMetrics = field.getFontMetrics(field.getFont());
size.width = fontMetrics.charWidth('a') * 40;
field.setPreferredSize(size);
}
private void updateMethodsTable() {
List<MemberInfo> methods = TestIntegrationUtils.extractClassMethods(
myTargetClass, myShowInheritedMethodsBox.isSelected());
@@ -95,16 +95,6 @@ public abstract class JavaDirectoryService {
@NotNull
public abstract PsiClass createInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException;
/**
* Checks if it's possible to create an interface with the specified name in the directory,
* and throws an exception if the creation is not possible. Does not actually modify
* anything.
*
* @param name the name of the interface to check creation possibility (not including the file extension).
* @throws IncorrectOperationException if the creation is not possible.
*/
public abstract void checkCreateInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException;
/**
* Creates an enumeration class with the specified name in the directory.
*
@@ -51,7 +51,7 @@ public class MethodSignatureUtil {
result += 37 * parameterTypes.length;
PsiType firstParamType = parameterTypes.length == 0 ? null : parameterTypes[0];
if (firstParamType != null) {
firstParamType = TypeConversionUtil.erasure(firstParamType);
firstParamType = TypeConversionUtil.erasure(firstParamType, signature.getSubstitutor());
result = 31*result + firstParamType.hashCode();
}
return result;
@@ -298,7 +298,9 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
PsiType substitutedBoundType = boundType.accept(mySimpleSubstitutionVisitor);
PsiWildcardType wildcardType = (PsiWildcardType)substituted;
if (substitutedBoundType != null && !(substitutedBoundType instanceof PsiWildcardType) && !substitutedBoundType.equalsToText("java.lang.Object")) {
if (originalBound == null || !TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(TypeConversionUtil.erasure(originalBound))) { //erasure is essential to avoid infinite recursion
if (originalBound == null ||
(!TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(TypeConversionUtil.erasure(originalBound)) &&
!TypeConversionUtil.erasure(substitutedBoundType).isAssignableFrom(originalBound))) { //erasure is essential to avoid infinite recursion
if (wildcardType.isExtends()) {
final PsiType glb = GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), substitutedBoundType);
if (glb != null) {
@@ -87,7 +87,7 @@ abstract class RunConfigurationExtension<T extends Ao> {
class F extends RunConfigurationExtension<Bo> {
<error descr="Method does not override method from its superclass">@Override</error>
@Override
protected <P extends Bo> SettingsEditor<P> createEditor(P configuration) {
return null;
}
@@ -0,0 +1,36 @@
class Zoo2 {
private boolean condition;
private final boolean condition2;
Zoo2(boolean condition2) {
this.condition2 = condition2;
}
Runnable foo() {
if (!condition) {
return new Runnable() {
public void run() {
if (condition) {
System.out.println("aaa");
}
}
};
}
if (!condition2) {
return new Runnable() {
public void run() {
if (<warning descr="Condition 'condition2' is always 'false'">condition2</warning>) {
System.out.println("aaa");
}
}
};
}
return <warning descr="'null' is returned by the method which isn't declared as @Nullable">null</warning>;
}
public void setCondition(boolean condition) {
this.condition = condition;
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2011 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
import com.intellij.codeInsight.navigation.CtrlMouseHandler
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
/**
* @author peter
*/
class JavaDocumentationTest extends LightCodeInsightFixtureTestCase {
public void testGenericMethod() {
myFixture.configureByText 'a.java', '''
class Bar<T> { java.util.List<T> foo(T param); }
class Foo {{
new Bar<String>().f<caret>oo();
}}
'''
def ref = myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset)
assert CtrlMouseHandler.getInfo(ref.resolve(), ref.element) == """Bar
java.util.List&lt;java.lang.String&gt; foo (java.lang.String param)"""
}
public void testGenericField() {
myFixture.configureByText 'a.java', '''
class Bar<T> { T field; }
class Foo {{
new Bar<Integer>().fi<caret>eld
}}
'''
def ref = myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset)
assert CtrlMouseHandler.getInfo(ref.resolve(), ref.element) == """Bar
java.lang.Integer field"""
}
}
@@ -1115,4 +1115,36 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
myFixture.type '*\n'
myFixture.checkResult "import java.lang.*<caret>"
}
public void testIntersectionTypesSOE() {
myFixture.configureByText("a.java", """
import java.util.*;
import java.io.*;
class SOE {
public boolean setLocation(Iterable<? extends File> path) {
return true;
}
public void compile(List<File> classpath) {
setLocation(<caret>);
}
}
""")
myFixture.completeBasic()
myFixture.type '*\n'
myFixture.checkResult """
import java.util.*;
import java.io.*;
class SOE {
public boolean setLocation(Iterable<? extends File> path) {
return true;
}
public void compile(List<File> classpath) {
setLocation(classpath);
}
}
"""
}
}
@@ -32,4 +32,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void testNullableAnonymousVolatile() throws Throwable { doTest(); }
public void testNullableAnonymousVolatileNotNull() throws Throwable { doTest(); }
public void testFieldInAnonymous() throws Throwable { doTest(); }
}
@@ -881,16 +881,6 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest {
"}");
}
public void testSpacesInsideEmptyParentheses() throws Exception {
final CommonCodeStyleSettings settings = getSettings();
settings.SPACE_WITHIN_METHOD_PARENTHESES = true;
settings.SPACE_WITHIN_METHOD_CALL_PARENTHESES = true;
doTextTest("public class Foo {\n" + " public void foo( ) {\n" + " foo( );\n" + " }\n" + "}",
"public class Foo {\n" + " public void foo() {\n" + " foo();\n" + " }\n" + "}");
}
public void testElseOnNewLine() throws Exception {
doTextTest("class Foo{\n" + "void foo() {\n" + "if (a)\n" + "return;\n" + "else\n" + "return;\n" + "}\n" + "}", "class Foo {\n" +
" void foo() {\n" +
@@ -1,24 +1,24 @@
/*
* Copyright 2000-2009 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.
*/
* Copyright 2000-2009 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.openapi.vfs.ex;
import com.intellij.openapi.vfs.VirtualFileManager;
public abstract class VirtualFileManagerEx extends VirtualFileManager {
public abstract void fireBeforeRefreshStart(boolean asynchronous);
public abstract void fireAfterRefreshFinish(boolean asynchronous);
}
@@ -24,7 +24,9 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.KeyedExtensionCollector;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
import com.intellij.openapi.vfs.newvfs.*;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.CachingVirtualFileSystem;
import com.intellij.openapi.vfs.newvfs.FileSystemPersistence;
import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ContainerUtil;
@@ -193,10 +195,10 @@ public class VirtualFileManagerImpl extends VirtualFileManagerEx {
@Override
public void notifyPropertyChanged(final VirtualFile virtualFile, final String property, final Object oldValue, final Object newValue) {
final Application application = ApplicationManager.getApplication();
application.invokeLater(new Runnable() {
final Runnable runnable = new Runnable() {
public void run() {
if (virtualFile.isValid() && !application.isDisposed()) {
application.runWriteAction(new Runnable(){
application.runWriteAction(new Runnable() {
public void run() {
List<VFilePropertyChangeEvent> events = Collections
.singletonList(new VFilePropertyChangeEvent(this, virtualFile, property, oldValue, newValue, false));
@@ -207,7 +209,8 @@ public class VirtualFileManagerImpl extends VirtualFileManagerEx {
});
}
}
}, ModalityState.NON_MODAL);
};
application.invokeLater(runnable, ModalityState.NON_MODAL);
}
public void fireBeforeRefreshStart(boolean asynchronous) {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.projectRoots.ui;
import com.google.common.collect.Lists;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
@@ -28,8 +27,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.JarFileSystem;
@@ -45,7 +42,6 @@ import com.intellij.util.containers.HashSet;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -77,21 +73,14 @@ public class PathEditor {
private boolean myEnabled = false;
private static final Icon ICON_INVALID = IconLoader.getIcon("/nodes/ppInvalid.png");
private static final Icon ICON_EMPTY = IconLoader.getIcon("/nodes/emptyNode.png");
private final String myDisplayName;
private final OrderRootType myOrderRootType;
private final FileChooserDescriptor myDescriptor;
public PathEditor(final String displayName,
final OrderRootType orderRootType,
final FileChooserDescriptor descriptor) {
myDisplayName = displayName;
myOrderRootType = orderRootType;
public PathEditor(final FileChooserDescriptor descriptor) {
myDescriptor = descriptor;
myDescriptor.putUserData(FileChooserDialog.PREFER_LAST_OVER_TO_SELECT, Boolean.TRUE);
myModel = createListModel();
}
protected void setEnabled(boolean enabled) {
myEnabled = enabled;
}
@@ -103,10 +92,6 @@ public class PathEditor {
protected void onSpecifyUrlButtonClicked() {
}
public String getDisplayName() {
return myDisplayName;
}
protected void setModified(boolean modified) {
myModified = modified;
}
@@ -115,20 +100,6 @@ public class PathEditor {
return myModified;
}
public OrderRootType getOrderRootType() {
return myOrderRootType;
}
public void apply(SdkModificator sdkModificator) {
sdkModificator.removeRoots(myOrderRootType);
// add all items
for (int i = 0; i < getRowCount(); i++) {
sdkModificator.addRoot(getValueAt(i), myOrderRootType);
}
setModified(false);
updateButtons();
}
public VirtualFile[] getRoots() {
final int count = getRowCount();
if (count == 0) {
@@ -152,15 +123,6 @@ public class PathEditor {
updateButtons();
}
public void reset(@Nullable SdkModificator modificator) {
if (modificator != null) {
resetPath(Lists.newArrayList(modificator.getRoots(myOrderRootType)));
}
else {
setEnabled(false);
}
}
public JComponent createComponent() {
myPanel = new JPanel(new GridBagLayout());
@@ -282,7 +244,7 @@ public class PathEditor {
return files;
}
protected void updateButtons() {
public void updateButtons() {
Object[] values = getSelectedRoots();
myRemoveButton.setEnabled((values.length > 0) && myEnabled);
myAddButton.setEnabled(myEnabled);
@@ -389,11 +351,11 @@ public class PathEditor {
return myList.getSelectedValues();
}
private int getRowCount() {
protected int getRowCount() {
return getListModel().getSize();
}
private VirtualFile getValueAt(int row) {
protected VirtualFile getValueAt(int row) {
return (VirtualFile)getListModel().get(row);
}
@@ -0,0 +1,61 @@
/*
* Copyright 2000-2011 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.openapi.projectRoots.ui;
import com.google.common.collect.Lists;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.roots.OrderRootType;
import org.jetbrains.annotations.Nullable;
public class SdkPathEditor extends PathEditor {
private final String myDisplayName;
private final OrderRootType myOrderRootType;
public SdkPathEditor(String displayName, OrderRootType orderRootType, FileChooserDescriptor descriptor) {
super(descriptor);
myDisplayName = displayName;
myOrderRootType = orderRootType;
}
public String getDisplayName() {
return myDisplayName;
}
public OrderRootType getOrderRootType() {
return myOrderRootType;
}
public void apply(SdkModificator sdkModificator) {
sdkModificator.removeRoots(myOrderRootType);
// add all items
for (int i = 0; i < getRowCount(); i++) {
sdkModificator.addRoot(getValueAt(i), myOrderRootType);
}
setModified(false);
updateButtons();
}
public void reset(@Nullable SdkModificator modificator) {
if (modificator != null) {
resetPath(Lists.newArrayList(modificator.getRoots(myOrderRootType)));
}
else {
setEnabled(false);
}
}
}
@@ -22,6 +22,7 @@ package com.intellij.openapi.roots.ui;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.KeyedExtensionFactory;
@@ -34,7 +35,7 @@ public interface OrderRootTypeUIFactory {
}
};
PathEditor createPathEditor(Sdk sdk);
SdkPathEditor createPathEditor(Sdk sdk);
Icon getIcon();
@@ -17,7 +17,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +33,7 @@ public class DocumentationOrderRootTypeUIFactory implements OrderRootTypeUIFacto
@Override
@Nullable
public PathEditor createPathEditor(Sdk sdk) {
public SdkPathEditor createPathEditor(Sdk sdk) {
return null;
}
@@ -62,8 +62,10 @@ import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class BraceHighlightingHandler {
private static final Key<List<RangeHighlighter>> BRACE_HIGHLIGHTERS_IN_EDITOR_VIEW_KEY = Key.create("BraceHighlighter.BRACE_HIGHLIGHTERS_IN_EDITOR_VIEW_KEY");
@@ -356,25 +358,25 @@ public class BraceHighlightingHandler {
}
private void highlightRightBrace(HighlighterIterator iterator, FileType fileType) {
int brace1End = iterator.getEnd();
TextRange brace1 = TextRange.create(iterator.getStart(), iterator.getEnd());
boolean matched = BraceMatchingUtil.matchBrace(myDocument.getCharsSequence(), fileType, iterator, false);
int brace2Start = iterator.atEnd() ? -1 : iterator.getStart();
TextRange brace2 = iterator.atEnd() ? null : TextRange.create(iterator.getStart(), iterator.getEnd());
highlightBraces(brace2Start, brace1End - 1, matched, false, fileType);
highlightBraces(brace2, brace1, matched, false, fileType);
}
private void highlightLeftBrace(HighlighterIterator iterator, boolean scopeHighlighting, FileType fileType) {
int brace1Start = iterator.getStart();
TextRange brace1Start = TextRange.create(iterator.getStart(), iterator.getEnd());
boolean matched = BraceMatchingUtil.matchBrace(myDocument.getCharsSequence(), fileType, iterator, true);
int brace2End = iterator.atEnd() ? -1 : iterator.getEnd() - 1;
TextRange brace2End = iterator.atEnd() ? null : TextRange.create(iterator.getStart(), iterator.getEnd());
highlightBraces(brace1Start, brace2End, matched, scopeHighlighting, fileType);
}
private void highlightBraces(final int lBraceOffset, int rBraceOffset, boolean matched, boolean scopeHighlighting, FileType fileType) {
private void highlightBraces(final TextRange lBrace, TextRange rBrace, boolean matched, boolean scopeHighlighting, FileType fileType) {
if (!matched && fileType == FileTypes.PLAIN_TEXT) {
return;
}
@@ -384,21 +386,21 @@ public class BraceHighlightingHandler {
matched ? scheme.getAttributes(CodeInsightColors.MATCHED_BRACE_ATTRIBUTES)
: scheme.getAttributes(CodeInsightColors.UNMATCHED_BRACE_ATTRIBUTES);
if (rBraceOffset >= 0 && !scopeHighlighting) {
highlightBrace(rBraceOffset, matched);
if (rBrace != null && !scopeHighlighting) {
highlightBrace(rBrace, matched);
}
if (lBraceOffset >= 0 && !scopeHighlighting) {
highlightBrace(lBraceOffset, matched);
if (lBrace != null && !scopeHighlighting) {
highlightBrace(lBrace, matched);
}
if (!myEditor.equals(FileEditorManager.getInstance(myProject).getSelectedTextEditor())) {
return;
}
if (lBraceOffset >= 0 && rBraceOffset >= 0) {
final int startLine = myEditor.offsetToLogicalPosition(lBraceOffset).line;
final int endLine = myEditor.offsetToLogicalPosition(rBraceOffset).line;
if (lBrace != null && rBrace !=null) {
final int startLine = myEditor.offsetToLogicalPosition(lBrace.getStartOffset()).line;
final int endLine = myEditor.offsetToLogicalPosition(rBrace.getEndOffset()).line;
if (endLine - startLine > 0) {
final Runnable runnable = new Runnable() {
public void run() {
@@ -424,7 +426,7 @@ public class BraceHighlightingHandler {
}
if (!scopeHighlighting) {
showScopeHint(lBraceOffset, lBraceOffset + 1);
showScopeHint(lBrace.getStartOffset(), lBrace.getEndOffset());
}
}
else {
@@ -434,7 +436,7 @@ public class BraceHighlightingHandler {
}
}
private void highlightBrace(int rBraceOffset, boolean matched) {
private void highlightBrace(TextRange braceRange, boolean matched) {
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
final TextAttributes attributes =
matched ? scheme.getAttributes(CodeInsightColors.MATCHED_BRACE_ATTRIBUTES)
@@ -443,7 +445,7 @@ public class BraceHighlightingHandler {
RangeHighlighter rbraceHighlighter =
myEditor.getMarkupModel().addRangeHighlighter(
rBraceOffset, rBraceOffset + 1, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE);
braceRange.getStartOffset(), braceRange.getEndOffset(), HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE);
rbraceHighlighter.setGreedyToLeft(false);
rbraceHighlighter.setGreedyToRight(false);
registerHighlighter(rbraceHighlighter);
@@ -25,6 +25,7 @@ import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Path2D;
/**
* @author Konstantin Bulenkov
@@ -65,8 +66,12 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
setOpaque(false);
setFont(UIUtil.isUnderAquaLookAndFeel() ? UIUtil.getLabelFont().deriveFont(11.0f) : getFont());
setIpad(new Insets(1, 2, 1, 2));
if (isPopupElement || !NavBarPanel.isDecorated()) {
setIpad(new Insets(1, 2, 1, 2));
} else {
setMyBorder(null);
setBorder(null);
}
update();
}
@@ -100,7 +105,9 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
final NavBarModel model = myPanel.getModel();
final boolean selected = isSelected();
setPaintFocusBorder(selected && !isPopupElement && myPanel.isNodePopupActive());
if (!NavBarPanel.isDecorated()) {
setPaintFocusBorder(selected && !isPopupElement && myPanel.isNodePopupActive());
}
setFocusBorderAroundIcon(false);
setBackground(selected && focused
@@ -119,6 +126,76 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
repaint();
}
@Override
protected void doPaint(Graphics2D g) {
if (isPopupElement || !NavBarPanel.isDecorated()) {
super.doPaint(g);
} else {
doPaintDecorated(g);
}
}
private void doPaintDecorated(Graphics2D g) {
setPaintFocusBorder(false);
setIpad(new Insets(0, 0, 0, 0));
Icon icon = myIcon;
final Color bg = getBackground();
g.setPaint(bg);
int w = getWidth();
int h = getHeight();
g.fillRect(0, 0, w, h);
icon.paintIcon(this, g, 3, (h - icon.getIconHeight()) / 2);
int x = doPaintText(g, icon.getIconWidth() + 6, false);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Path2D.Double p = new Path2D.Double();
g.translate(x, 0);
p.moveTo(0, 0); //
p.lineTo(10 , h / 2); // |\
p.lineTo(0, h); // |/
p.lineTo(0, 0);
g.setPaint(getBackground());
g.fill(p);
if (isLastElement()) {
Path2D.Double path = new Path2D.Double();
path.moveTo(0, 0);
path.lineTo(10, h / 2); // ___
path.lineTo(0, h); // \ |
path.lineTo(12, h); // /_|
path.lineTo(12, 0);
path.lineTo(0, 0);
g.setPaint(isNextSelected() ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground());
g.fill(path);
path = new Path2D.Double();
path.moveTo(0, 0); //
path.lineTo(10, h / 2); // \
path.lineTo(0, h); // /
g.setPaint(Color.GRAY);
g.draw(path);
}
}
private boolean isLastElement() {
return myIndex != myPanel.getModel().size() - 1;
}
@Override
public Dimension getPreferredSize() {
final Dimension size = super.getPreferredSize();
if (! isPopupElement && NavBarPanel.isDecorated()) {
size.width += 10 + 2*3;
size.height += 6;
}
return size;
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
private boolean isFocused() {
final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
return isPopupElement || (focusOwner == myPanel && !myPanel.isNodePopupShowing());
@@ -168,4 +245,9 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
@Override
public void dispose() {
}
private boolean isNextSelected() {
return myIndex == myPanel.getModel().getSelectedIndex() - 1;
}
}
@@ -42,6 +42,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -99,7 +100,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
private RelativePoint myLocationCache;
public NavBarPanel(final Project project) {
super(new FlowLayout(FlowLayout.LEFT, 5, 0));
super(new FlowLayout(FlowLayout.LEFT, isDecorated() ? 0 : 5, 0));
myProject = project;
myModel = new NavBarModel(myProject);
myIdeView = new NavBarIdeView(this);
@@ -108,7 +109,9 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
PopupHandler.installPopupHandler(this, IdeActions.GROUP_NAVBAR_POPUP, ActionPlaces.NAVIGATION_BAR);
setBorder(new NavBarBorder(false, -1));
if (!isDecorated()) {
setBorder(new NavBarBorder(false, -1));
}
setOpaque(false);
myCopyPasteDelegator = new CopyPasteDelegator(myProject, NavBarPanel.this) {
@@ -124,7 +127,9 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
Disposer.register(project, this);
}
public static boolean isDecorated() {
return Registry.is("navbar.is.decorated");
}
public boolean isNodePopupActive() {
return myNodePopup != null && myNodePopup.isVisible();
@@ -55,7 +55,7 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx, Modifiab
final TextAttributes attributes = section.getTextAttributes();
renderer.append(section.getText(), SimpleTextAttributes.fromTextAttributes(attributes));
}
setIcon(myIcon);
renderer.setIcon(myIcon);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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.
@@ -19,6 +19,7 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -40,10 +41,10 @@ import java.util.List;
*/
public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRenderer, TableCellEditor, JBPopupListener {
private static final Icon ARROW_ICON = IconLoader.getIcon("/general/comboArrow.png");
private final T[] myValues;
private WeakReference<ListPopup> myPopupRef;
private ChangeEvent myChangeEvent = null;
private T myValue;
protected EventListenerList myListenerList = new EventListenerList();
@@ -73,8 +74,6 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
return value.toString();
}
protected Runnable onChosen(@NotNull final T value) {
stopCellEditing(value);
@@ -89,24 +88,30 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
protected void paintComponent(Graphics g) {
super.paintComponent(g);
final Rectangle r = getBounds();
final Insets i = getInsets();
if (getText() != null && getText().length() != 0) ARROW_ICON.paintIcon(this, g, r.width - i.right - ARROW_ICON.getIconWidth(), i.top);
if (!StringUtil.isEmpty(getText())) {
final Rectangle r = getBounds();
final Insets i = getInsets();
final int x = r.width - i.right - ARROW_ICON.getIconWidth();
final int y = i.top + (r.height - i.top - i.bottom - ARROW_ICON.getIconHeight()) / 2;
ARROW_ICON.paintIcon(this, g, x, y);
}
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
customizeComponent((T) value, isSelected);
@SuppressWarnings("unchecked") final T t = (T)value;
customizeComponent(t, table, isSelected);
return this;
}
public Component getTableCellEditorComponent(JTable table, final Object value, boolean isSelected, final int row, final int column) {
myValue = (T) value;
customizeComponent((T) value, isSelected);
@SuppressWarnings("unchecked") final T t = (T)value;
myValue = t;
customizeComponent(t, table, isSelected);
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showPopup((T) value, row);
showPopup(t, row);
}
});
@@ -159,6 +164,14 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
fireEditingCanceled();
}
protected void customizeComponent(final T value, final JTable table, final boolean isSelected) {
setOpaque(true);
setText(value == null ? "" : getTextFor(value));
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
}
/** @deprecated use {@linkplain #customizeComponent(Object, javax.swing.JTable, boolean)} (to remove in IDEA 12) */
protected void customizeComponent(T value, boolean isSelected) {
setOpaque(true);
setText(value == null ? "" : getTextFor(value));
@@ -172,7 +185,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
public boolean isCellEditable(EventObject event) {
if (event instanceof MouseEvent) {
return ((MouseEvent)event).getClickCount() >= 2;
return ((MouseEvent)event).getClickCount() >= 2;
}
return true;
@@ -199,33 +212,35 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = myListenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if (myChangeEvent == null)
myChangeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingStopped(myChangeEvent);
}
// Guaranteed to return a non-null array
Object[] listeners = myListenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (myChangeEvent == null) {
myChangeEvent = new ChangeEvent(this);
}
((CellEditorListener)listeners[i + 1]).editingStopped(myChangeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = myListenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if (myChangeEvent == null)
myChangeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingCanceled(myChangeEvent);
}
// Guaranteed to return a non-null array
Object[] listeners = myListenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CellEditorListener.class) {
// Lazily create the event:
if (myChangeEvent == null) {
myChangeEvent = new ChangeEvent(this);
}
((CellEditorListener)listeners[i + 1]).editingCanceled(myChangeEvent);
}
}
}
private void hidePopup() {
@@ -20,11 +20,11 @@ import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.InplaceButton;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBViewport;
import com.intellij.ui.speedSearch.ListWithFilter;
@@ -251,7 +251,7 @@ public class PopupChooserBuilder {
builder.setDimensionServiceKey(null, myDimensionServiceKey, false).setRequestFocus(myRequestFocus).setResizable(myForceResizable)
.setMovable(myForceMovable).setTitle(myForceMovable ? myTitle : null).setCancelCallback(myCancelCallback).setAlpha(myAlpha)
.setFocusOwners(myFocusOwners).setCancelKeyEnabled(myCancelKeyEnabled && !(myChooserComponent instanceof ListWithFilter)).
setAdText(myAd, myAdAlignment).setKeyboardActions(myKeyboardActions).setMayBeParent(myMayBeParent);
setAdText(myAd, myAdAlignment).setKeyboardActions(myKeyboardActions).setMayBeParent(myMayBeParent).setLocateWithinScreenBounds(true);
if (myCommandButton != null) {
builder.setCommandButton(myCommandButton);
@@ -418,12 +418,13 @@ public class PopupChooserBuilder {
if (size >= 0 && size <= 20) {
return list.getPreferredSize();
} else {
final Dimension even = super.preferredLayoutSize(parent);
final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(null);
final JComponent c = ideFrame.getComponent();
final Dimension sz = super.preferredLayoutSize(parent);
final Point p = RelativePoint.getNorthWestOf(myList).getScreenPoint();
final Rectangle screen = ScreenUtil.getScreenRectangle(p);
final int bordersEtc = 20;
final int maxWidth = c.getWidth() - SwingUtilities.convertPoint(myList, new Point(0, 0), c).x - 2 * bordersEtc;
return new Dimension(Math.min(maxWidth, even.width) + bordersEtc, even.height + list.getCellBounds(0, 0).height / 2);
final int maxWidth = Math.abs(screen.x + screen.width - p.x) - 2 * bordersEtc;
return new Dimension(Math.min(maxWidth, sz.width) + bordersEtc, sz.height + list.getCellBounds(0, 0).height / 2);
}
}
};
@@ -18,6 +18,8 @@ package com.intellij.ui;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* @author Konstantin Bulenkov
@@ -35,6 +37,12 @@ class ListToolbarDecorator extends ToolbarDecorator {
updateButtons();
}
});
myList.addPropertyChangeListener("enabled", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateButtons();
}
});
}
private void createActions() {
@@ -58,7 +66,7 @@ class ListToolbarDecorator extends ToolbarDecorator {
ListUtil.moveSelectedItemsDown(myList);
updateButtons();
}
};
};
}
@Override
@@ -69,21 +77,29 @@ class ListToolbarDecorator extends ToolbarDecorator {
@Override
protected void updateButtons() {
final AddRemoveUpDownPanel p = getPanel();
if (myList.isEnabled() && p != null) {
final int index = myList.getSelectedIndex();
if (0 <= index && index < myList.getModel().getSize()) {
final boolean downEnable = myList.getMaxSelectionIndex() < myList.getModel().getSize() - 1;
final boolean upEnable = myList.getMinSelectionIndex() > 0;
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable);
} else {
if (p != null) {
if (myList.isEnabled()) {
final int index = myList.getSelectedIndex();
if (0 <= index && index < myList.getModel().getSize()) {
final boolean downEnable = myList.getMaxSelectionIndex() < myList.getModel().getSize() - 1;
final boolean upEnable = myList.getMinSelectionIndex() > 0;
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable);
}
else {
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false);
}
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true);
}
else {
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false);
}
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true);
}
}
}
@@ -43,6 +43,7 @@ import java.util.Map;
*
* @author Vladimir Kondratyev
*/
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "FieldAccessedSynchronizedAndUnsynchronized", "UnusedDeclaration"})
public class SimpleColoredComponent extends JComponent implements Accessible {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.SimpleColoredComponent");
public static final Color STYLE_SEARCH_MATCH_BACKGROUND = new Color(250, 250, 250, 140);
@@ -78,7 +79,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
* if the component represents a selected item in a focused JList.
* Border can be <code>null</code>.
*/
private MyBorder myBorder;
private Border myBorder;
private int myMainTextLastIndex = -1;
@@ -107,6 +108,8 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Appends string fragments to existing ones. Appended string
* will have specified <code>attributes</code>.
* @param fragment text fragment
* @param attributes text attributes
*/
public final void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes) {
append(fragment, attributes, myMainTextLastIndex < 0);
@@ -115,17 +118,22 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Appends string fragments to existing ones. Appended string
* will have specified <code>attributes</code>.
* @param fragment text fragment
* @param attributes text attributes
* @param isMainText main text of not
*/
public void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes, boolean isMainText) {
synchronized (this) {
myFragments.add(fragment);
myAttributes.add(attributes);
if (isMainText) {
myMainTextLastIndex = myFragments.size() - 1;
}
}
_append(fragment, attributes, isMainText);
revalidateAndRepaint();
}
private synchronized void _append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes, boolean isMainText) {
myFragments.add(fragment);
myAttributes.add(attributes);
if (isMainText) {
myMainTextLastIndex = myFragments.size() - 1;
}
}
private void revalidateAndRepaint() {
if (myAutoInvalidate) {
@@ -136,19 +144,21 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
}
public void append(@NotNull final String fragment, @NotNull final SimpleTextAttributes attributes, Object tag) {
synchronized (this) {
append(fragment, attributes);
if (myFragmentTags == null) {
myFragmentTags = new ArrayList<Object>();
}
while(myFragmentTags.size() < myFragments.size()-1) {
myFragmentTags.add(null);
}
myFragmentTags.add(tag);
}
_append(fragment, attributes, tag);
revalidateAndRepaint();
}
private synchronized void _append(String fragment, SimpleTextAttributes attributes, Object tag) {
append(fragment, attributes);
if (myFragmentTags == null) {
myFragmentTags = new ArrayList<Object>();
}
while(myFragmentTags.size() < myFragments.size()-1) {
myFragmentTags.add(null);
}
myFragmentTags.add(tag);
}
public synchronized void appendAlign(int alignWidth) {
final int alignIndex = myFragments.size()-1;
myAligns.put(alignIndex, alignWidth);
@@ -159,18 +169,20 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
* They are icon, text fragments and their attributes, "paint focus border".
*/
public void clear() {
synchronized (this) {
myIcon = null;
myPaintFocusBorder = false;
myFragments.clear();
myAttributes.clear();
myFragmentTags = null;
myMainTextLastIndex = -1;
myAligns.clear();
}
_clear();
revalidateAndRepaint();
}
private synchronized void _clear() {
myIcon = null;
myPaintFocusBorder = false;
myFragments.clear();
myAttributes.clear();
myFragmentTags = null;
myMainTextLastIndex = -1;
myAligns.clear();
}
/**
* @return component's icon. This method returns <code>null</code>
* if there is no icon.
@@ -181,6 +193,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Sets a new component icon
* @param icon icon
*/
public final void setIcon(final @Nullable Icon icon) {
myIcon = icon;
@@ -196,6 +209,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Sets specified internal paddings
* @param ipad insets
*/
public void setIpad(final Insets ipad) {
myIpad = ipad;
@@ -213,6 +227,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Sets a new gap between icon and text
*
* @param iconTextGap the gap between text and icon
* @throws java.lang.IllegalArgumentException
* if the <code>iconTextGap</code>
* has a negative value
@@ -226,16 +241,17 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
revalidateAndRepaint();
}
public MyBorder getMyBorder() {
public Border getMyBorder() {
return myBorder;
}
public void setMyBorder(@Nullable MyBorder border) {
public void setMyBorder(@Nullable Border border) {
myBorder = border;
}
/**
* Sets whether focus border is painted or not
* @param paintFocusBorder <code>true</code> or <code>false</code>
*/
protected final void setPaintFocusBorder(final boolean paintFocusBorder) {
myPaintFocusBorder = paintFocusBorder;
@@ -246,6 +262,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
/**
* Sets whether focus border extends to icon or not. If so then
* component also extends the selection.
* @param focusBorderAroundIcon <code>true</code> or <code>false</code>
*/
protected final void setFocusBorderAroundIcon(final boolean focusBorderAroundIcon) {
myFocusBorderAroundIcon = focusBorderAroundIcon;
@@ -274,6 +291,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
return computePreferredSize(false);
}
@Nullable
public synchronized Object getFragmentTag(int index) {
if (myFragmentTags != null && index < myFragmentTags.size()) {
return myFragmentTags.get(index);
@@ -368,7 +386,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
protected void paintComponent(final Graphics g) {
try {
doPaint(g);
_doPaint(g);
}
catch (RuntimeException e) {
LOG.error(logSwingPath(), e);
@@ -376,55 +394,67 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
}
}
protected synchronized void doPaint(final Graphics g) {
private synchronized void _doPaint(final Graphics g) {
checkCanPaint(g);
int xOffset = 0;
// Paint icon and its background
final Icon icon = myIcon; // guard against concurrent modification (IDEADEV-12635)
doPaint((Graphics2D)g);
}
protected void doPaint(final Graphics2D g) {
int offset = 0;
final Icon icon = myIcon; // guard against concurrent modification (IDEADEV-12635)
if (icon != null) {
final Container parent = getParent();
Color iconBackgroundColor = null;
if (isOpaque() || isIconOpaque()) {
if (parent != null && !myFocusBorderAroundIcon && !UIUtil.isFullRowSelectionLAF()) {
iconBackgroundColor = parent.getBackground();
}
else {
iconBackgroundColor = getBackground();
}
}
if (iconBackgroundColor != null) {
g.setColor(iconBackgroundColor);
g.fillRect(0, 0, icon.getIconWidth() + myIpad.left + myIconTextGap, getHeight());
}
paintIcon(g, icon);
xOffset += myIpad.left + icon.getIconWidth() + myIconTextGap;
doPaintIcon(g, icon);
offset += myIpad.left + icon.getIconWidth() + myIconTextGap;
}
doPaintTextBackground(g, offset);
doPaintText(g, offset, myFocusBorderAroundIcon || icon == null);
}
protected void doPaintTextBackground(Graphics2D g, int offset) {
if (isOpaque() || shouldDrawBackground()) {
// Paint text background
g.setColor(getBackground());
g.fillRect(xOffset, 0, getWidth() - xOffset, getHeight());
g.fillRect(offset, 0, getWidth() - offset, getHeight());
}
}
protected void doPaintIcon(Graphics2D g, Icon icon) {
final Container parent = getParent();
Color iconBackgroundColor = null;
if (isOpaque() || isIconOpaque()) {
if (parent != null && !myFocusBorderAroundIcon && !UIUtil.isFullRowSelectionLAF()) {
iconBackgroundColor = parent.getBackground();
}
else {
iconBackgroundColor = getBackground();
}
}
if (iconBackgroundColor != null) {
g.setColor(iconBackgroundColor);
g.fillRect(0, 0, icon.getIconWidth() + myIpad.left + myIconTextGap, getHeight());
}
paintIcon(g, icon);
}
protected int doPaintText(Graphics2D g, int offset, boolean focusAroundIcon) {
// If there is no icon, then we have to add left internal padding
if (xOffset == 0) {
xOffset = myIpad.left;
if (offset == 0) {
offset = myIpad.left;
}
int textStart = xOffset;
int textStart = offset;
if (myBorder != null) {
xOffset += myBorder.getBorderInsets(this).left;
offset += myBorder.getBorderInsets(this).left;
}
final List<Object[]> searchMatches = new ArrayList<Object[]>();
// Paint text
UIUtil.applyRenderingHints(g);
applyAdditionalHints(g);
for (int i = 0; i < myFragments.size(); i++) {
final SimpleTextAttributes attributes = myAttributes.get(i);
Font font = g.getFont();
@@ -440,7 +470,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
final Color bgColor = attributes.getBgColor();
if (isOpaque() && bgColor != null) {
g.setColor(bgColor);
g.fillRect(xOffset, 0, fragmentWidth, getHeight());
g.fillRect(offset, 0, fragmentWidth, getHeight());
}
Color color = attributes.getFgColor();
@@ -457,17 +487,17 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
if (!attributes.isSearchMatch()) {
if (shouldDrawMacShadow()) {
g.setColor(STYLE_SEARCH_MATCH_BACKGROUND);
g.drawString(fragment, xOffset, textBaseline + 1);
g.drawString(fragment, offset, textBaseline + 1);
}
g.setColor(color);
g.drawString(fragment, xOffset, textBaseline);
g.drawString(fragment, offset, textBaseline);
}
// 1. Strikeout effect
if (attributes.isStrikeout()) {
final int strikeOutAt = textBaseline + (metrics.getDescent() - metrics.getAscent()) / 2;
UIUtil.drawLine(g, xOffset, strikeOutAt, xOffset + fragmentWidth, strikeOutAt);
UIUtil.drawLine(g, offset, strikeOutAt, offset + fragmentWidth, strikeOutAt);
}
// 2. Waved effect
if (attributes.isWaved()) {
@@ -475,7 +505,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
g.setColor(attributes.getWaveColor());
}
final int wavedAt = textBaseline + 1;
for (int x = xOffset; x <= xOffset + fragmentWidth; x += 4) {
for (int x = offset; x <= offset + fragmentWidth; x += 4) {
UIUtil.drawLine(g, x, wavedAt, x + 2, wavedAt + 2);
UIUtil.drawLine(g, x + 3, wavedAt + 1, x + 4, wavedAt);
}
@@ -483,41 +513,40 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
// 3. Underline
if (attributes.isUnderline()) {
final int underlineAt = textBaseline + 1;
UIUtil.drawLine(g, xOffset, underlineAt, xOffset + fragmentWidth, underlineAt);
UIUtil.drawLine(g, offset, underlineAt, offset + fragmentWidth, underlineAt);
}
// 4. Bold Dotted Line
if (attributes.isBoldDottedLine()) {
final int dottedAt = SystemInfo.isMac ? textBaseline : textBaseline + 1;
final Color lineColor = attributes.getWaveColor();
UIUtil.drawBoldDottedLine((Graphics2D)g, xOffset, xOffset + fragmentWidth, dottedAt, bgColor, lineColor, isOpaque());
UIUtil.drawBoldDottedLine(g, offset, offset + fragmentWidth, dottedAt, bgColor, lineColor, isOpaque());
}
if (attributes.isSearchMatch()) {
searchMatches.add(new Object[] {xOffset, xOffset + fragmentWidth, textBaseline, fragment, g.getFont()});
searchMatches.add(new Object[] {offset, offset + fragmentWidth, textBaseline, fragment, g.getFont()});
}
final Integer fixedWidth = myAligns.get(i);
if (fixedWidth != null && fragmentWidth < fixedWidth.intValue()) {
//if (fixedWidth != null) {
xOffset += fixedWidth.intValue();
//if (fixedWidth != null) {
offset += fixedWidth.intValue();
} else {
xOffset += fragmentWidth;
offset += fragmentWidth;
}
}
// Paint focus border around the text and icon (if necessary)
if (myPaintFocusBorder && myBorder != null) {
if (myFocusBorderAroundIcon || icon == null) {
if (focusAroundIcon) {
myBorder.paintBorder(this, g, 0, 0, getWidth(), getHeight());
}
else {
} else {
myBorder.paintBorder(this, g, textStart, 0, getWidth() - textStart, getHeight());
}
}
// draw search matches after all
for (final Object[] info: searchMatches) {
UIUtil.drawSearchMatch((Graphics2D)g, (Integer) info[0], (Integer) info[1], getHeight());
UIUtil.drawSearchMatch(g, (Integer) info[0], (Integer) info[1], getHeight());
g.setFont((Font) info[4]);
if (shouldDrawMacShadow()) {
@@ -528,8 +557,9 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
g.setColor(new Color(50, 50, 50));
g.drawString((String) info[3], (Integer) info[0], (Integer) info[2]);
}
return offset;
}
protected boolean shouldDrawMacShadow() {
return false;
}
@@ -583,8 +613,8 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
}
protected void setBorderInsets(Insets insets) {
if (myBorder != null) {
myBorder.setInsets(insets);
if (myBorder instanceof MyBorder) {
((MyBorder)myBorder).setInsets(insets);
}
revalidateAndRepaint();
@@ -617,7 +647,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
@Override
public String toString() {
StringBuffer result = new StringBuffer();
final StringBuilder result = new StringBuilder();
for (String each : myFragments) {
result.append(each);
}
@@ -662,6 +692,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible {
return 0;
}
@Nullable
@Override
public Accessible getAccessibleChild(int i) {
return null;
@@ -27,6 +27,8 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableModel;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* @author Konstantin Bulenkov
@@ -48,6 +50,12 @@ class TableToolbarDecorator extends ToolbarDecorator {
updateButtons();
}
});
myTable.addPropertyChangeListener("enabled", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateButtons();
}
});
}
@Override
@@ -57,21 +65,30 @@ class TableToolbarDecorator extends ToolbarDecorator {
protected void updateButtons() {
final AddRemoveUpDownPanel p = getPanel();
if (myTable.isEnabled() && p != null) {
final int index = myTable.getSelectedRow();
final int size = myTableModel.getRowCount();
if (0 <= index && index < size) {
final boolean downEnable = myTable.getSelectionModel().getMaxSelectionIndex() < size - 1;
final boolean upEnable = myTable.getSelectionModel().getMinSelectionIndex() > 0;
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable);
} else {
if (p != null) {
if (myTable.isEnabled()) {
final int index = myTable.getSelectedRow();
final int size = myTableModel.getRowCount();
if (0 <= index && index < size) {
final boolean downEnable = myTable.getSelectionModel().getMaxSelectionIndex() < size - 1;
final boolean upEnable = myTable.getSelectionModel().getMinSelectionIndex() > 0;
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable);
}
else {
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false);
}
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true);
}
else {
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false);
p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false);
}
p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true);
}
}
@@ -24,6 +24,7 @@ import com.intellij.util.ui.ElementProducer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
@@ -38,6 +39,18 @@ import java.util.List;
*/
@SuppressWarnings("UnusedDeclaration")
public abstract class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.ListenerFactory {
private static final Comparator<AnAction> ACTION_BUTTONS_SORTER = new Comparator<AnAction>() {
@Override
public int compare(AnAction a1, AnAction a2) {
if (a1 instanceof AnActionButton && a2 instanceof AnActionButton) {
final JComponent c1 = ((AnActionButton)a1).getContextComponent();
final JComponent c2 = ((AnActionButton)a2).getContextComponent();
return c1.hasFocus() ? -1 : c2.hasFocus() ? 1 : 0;
}
return 0;
}
};
protected Border myToolbarBorder;
protected boolean myAddActionEnabled;
protected boolean myRemoveActionEnabled;
@@ -57,26 +70,13 @@ public abstract class ToolbarDecorator implements DataProvider, AddRemoveUpDownP
private Dimension myPreferredSize;
private AddRemoveUpDownPanel myPanel;
public ToolbarDecorator() {
}
protected abstract JComponent getComponent();
protected abstract void updateButtons();
final AddRemoveUpDownPanel getPanel() {
return myPanel;
}
private static final Comparator<AnAction> ACTION_BUTTONS_SORTER = new Comparator<AnAction>() {
@Override
public int compare(AnAction a1, AnAction a2) {
if (a1 instanceof AnActionButton && a2 instanceof AnActionButton) {
final JComponent c1 = ((AnActionButton)a1).getContextComponent();
final JComponent c2 = ((AnActionButton)a2).getContextComponent();
return c1.hasFocus() ? -1 : c2.hasFocus() ? 1 : 0;
}
return 0;
}
};
protected ToolbarDecorator initPositionAndBorder() {
myToolbarPosition = SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.RIGHT;
@@ -240,7 +240,6 @@ public abstract class ToolbarDecorator implements DataProvider, AddRemoveUpDownP
return null;
}
private Object getPlacement() {
switch (myToolbarPosition) {
case TOP: return BorderLayout.NORTH;
@@ -300,23 +299,27 @@ public abstract class ToolbarDecorator implements DataProvider, AddRemoveUpDownP
};
}
@Nullable
public static AnActionButton findAddButton(@NotNull JComponent container) {
return findButton(container, AddRemoveUpDownPanel.Buttons.ADD);
}
@Nullable
public static AnActionButton findRemoveButton(@NotNull JComponent container) {
return findButton(container, AddRemoveUpDownPanel.Buttons.REMOVE);
}
@Nullable
public static AnActionButton findUpButton(@NotNull JComponent container) {
return findButton(container, AddRemoveUpDownPanel.Buttons.UP);
}
@Nullable
public static AnActionButton findDownButton(@NotNull JComponent container) {
return findButton(container, AddRemoveUpDownPanel.Buttons.DOWN);
}
@Nullable
private static AnActionButton findButton(JComponent comp, AddRemoveUpDownPanel.Buttons type) {
final AddRemoveUpDownPanel panel = UIUtil.findComponentOfType(comp, AddRemoveUpDownPanel.class);
if (panel != null) {
@@ -149,8 +149,9 @@ public class MacOSApplicationProvider implements ApplicationComponent {
Foundation.registerObjcClassPair(checkForUpdatesClass);
ID checkForUpdates = Foundation.invoke("NSCheckForUpdates", "alloc");
Foundation.invoke(checkForUpdates, Foundation.createSelector("initWithTitle:action:keyEquivalent:"), Foundation.cfString("Check for Updates..."),
Foundation.createSelector("checkForUpdates"), Foundation.cfString(""));
Foundation.invoke(checkForUpdates, Foundation.createSelector("initWithTitle:action:keyEquivalent:"),
Foundation.nsString("Check for Updates..."),
Foundation.createSelector("checkForUpdates"), Foundation.nsString(""));
Foundation.invoke(checkForUpdates, Foundation.createSelector("setTarget:"), checkForUpdates);
Foundation.invoke(appMenu, Foundation.createSelector("insertItem:atIndex:"), checkForUpdates, 1);
@@ -18,21 +18,17 @@ package com.intellij.ide.plugins;
import com.intellij.CommonBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.startup.StartupActionScriptManager;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@@ -160,12 +156,7 @@ public class PluginInstaller {
}
synchronized (PluginManager.lock) {
final BuildNumber buildNumber = ApplicationInfo.getInstance().getBuild();
final @NonNls String url = RepositoryHelper.DOWNLOAD_URL +
URLEncoder.encode(pluginNode.getPluginId().getIdString(), "UTF8") +
"&build=" + buildNumber.asString();
final PluginDownloader downloader =
new PluginDownloader(pluginNode.getPluginId().getIdString(), url, null, null, pluginNode.getName());
final PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode);
if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
downloader.install();
pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED);
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.xml.sax.SAXException;
import javax.swing.*;
@@ -52,7 +53,7 @@ public class RepositoryHelper {
@NonNls private static final String FILENAME = "filename=";
@NonNls public static final String extPluginsFile = "availables.xml";
public static ArrayList<IdeaPluginDescriptor> process(JLabel label) throws IOException, ParserConfigurationException, SAXException {
public static ArrayList<IdeaPluginDescriptor> process(@Nullable JLabel label) throws IOException, ParserConfigurationException, SAXException {
ArrayList<IdeaPluginDescriptor> plugins = null;
try {
BuildNumber buildNumber = ApplicationInfo.getInstance().getBuild();
@@ -85,7 +86,8 @@ public class RepositoryHelper {
return plugins;
}
private static void setLabelText(final JLabel label, final String message) {
private static void setLabelText(@Nullable final JLabel label, final String message) {
if (label == null) return;
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
label.setText(message);
@@ -53,10 +53,10 @@ public class MacRestarter {
final long processId = Foundation.invoke(app, Foundation.createSelector("processIdentifier")).longValue();
final ID args = Foundation.invoke(Foundation.getClass("NSArray"), Foundation.createSelector("arrayWithObjects:"),
new Object[]{Foundation.cfString(appPath), Foundation.cfString(String.valueOf(processId))});
new Object[]{Foundation.nsString(appPath), Foundation.nsString(String.valueOf(processId))});
Foundation.invoke(Foundation.getClass("NSTask"), Foundation.createSelector("launchedTaskWithLaunchPath:arguments:"),
Foundation.cfString(relaunchPath), args);
Foundation.nsString(relaunchPath), args);
}
}
}
@@ -16,21 +16,23 @@
package com.intellij.openapi.editor.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.*;
import java.util.List;
/**
* @author max
*/
public class ComplementaryFontsRegistry {
private static final Object lock = new String("common lock");
private static final ArrayList<String> ourFontNames;
private static final List<String> ourFontNames;
private static final Set<String> ourStyledFontNames;
private static final LinkedHashMap<FontKey, FontInfo> ourUsedFonts;
private static FontKey ourSharedKeyInstance = new FontKey("", 0, 0);
private static FontInfo ourSharedDefaultFont;
@@ -72,11 +74,22 @@ public class ComplementaryFontsRegistry {
@NonNls private static final String ITALIC_SUFFIX = ".italic";
static {
ourStyledFontNames = new HashSet<String>();
ourFontNames = new ArrayList<String>();
if (ApplicationManager.getApplication().isUnitTestMode()) {
ourFontNames.add("Monospaced");
} else {
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (SystemInfo.isMac) {
Font[] allFonts = graphicsEnvironment.getAllFonts();
for (Font font : allFonts) {
String name = font.getName();
if (name.endsWith("-Italic") || name.endsWith("-Bold") || name.endsWith("-BoldItalic")) {
ourStyledFontNames.add(font.getName());
}
}
}
String[] fontNames = graphicsEnvironment.getAvailableFontFamilyNames();
for (final String fontName : fontNames) {
if (!fontName.endsWith(BOLD_SUFFIX) && !fontName.endsWith(ITALIC_SUFFIX)) {
@@ -87,12 +100,30 @@ public class ComplementaryFontsRegistry {
ourUsedFonts = new LinkedHashMap<FontKey, FontInfo>();
}
private static Pair<String, Integer> fontFamily(String familyName, int style) {
if (!SystemInfo.isMac || style == 0) return Pair.create(familyName, style);
StringBuilder st = new StringBuilder(familyName).append('-');
if ((style & Font.BOLD) == Font.BOLD) {
st.append("Bold");
}
if ((style & Font.ITALIC) == Font.ITALIC) {
st.append("Italic");
}
String styledFamilyName = st.toString();
boolean found = ourStyledFontNames.contains(styledFamilyName);
return Pair.create(found ? styledFamilyName : familyName, found ? Font.PLAIN : style);
}
public static FontInfo getFontAbleToDisplay(char c, int size, int style, @NotNull String defaultFontFamily) {
synchronized (lock) {
Pair<String, Integer> p = fontFamily(defaultFontFamily, style);
if (ourSharedKeyInstance.mySize == size &&
ourSharedKeyInstance.myStyle == style &&
ourSharedKeyInstance.myStyle == p.getSecond() &&
ourSharedKeyInstance.myFamilyName != null &&
ourSharedKeyInstance.myFamilyName.equals(defaultFontFamily) &&
ourSharedKeyInstance.myFamilyName.equals(p.getFirst()) &&
ourSharedDefaultFont != null &&
( c < 128 ||
ourSharedDefaultFont.canDisplay(c)
@@ -101,13 +132,13 @@ public class ComplementaryFontsRegistry {
return ourSharedDefaultFont;
}
ourSharedKeyInstance.myFamilyName = defaultFontFamily;
ourSharedKeyInstance.myFamilyName = p.getFirst();
ourSharedKeyInstance.mySize = size;
ourSharedKeyInstance.myStyle = style;
ourSharedKeyInstance.myStyle = p.getSecond();
FontInfo defaultFont = ourUsedFonts.get(ourSharedKeyInstance);
if (defaultFont == null) {
defaultFont = new FontInfo(defaultFontFamily, size, style);
defaultFont = new FontInfo(p.getFirst(), size, p.getSecond());
ourUsedFonts.put(ourSharedKeyInstance, defaultFont);
ourSharedKeyInstance = new FontKey("", 0, 0);
}
@@ -131,7 +131,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private final EditorGutterComponentImpl myGutterComponent;
static {
ComplementaryFontsRegistry.getFontAbleToDisplay(' ', 0,0,""); // load costly font info
ComplementaryFontsRegistry.getFontAbleToDisplay(' ', 0,0, UIManager.getFont("Label.font").getFamily()); // load costly font info
}
private final CommandProcessor myCommandProcessor;
@@ -419,8 +419,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
private void initDialog(boolean shouldShowBackground, String cancelText) {
if (UIUtil.isUnderAquaLookAndFeel()) {
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, myTextLabel);
UIUtil.applyStyle(UIUtil.ComponentStyle.MINI, myText2Label);
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, myText2Label);
}
myProgressBar.setPreferredSize(new Dimension(UIUtil.isUnderAquaLookAndFeel() ? 350 : 450, -1));
@@ -59,7 +59,7 @@ public class ShadowBorderPainter {
public static BufferedImage createShadow(final JComponent c, final int width, final int height, boolean isPopup) {
final GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
getDefaultScreenDevice().getDefaultConfiguration();
final BufferedImage image = graphicsConfiguration.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
final Graphics2D g = image.createGraphics();
@@ -77,24 +77,23 @@ public class ShadowBorderPainter {
topLeft.paintIcon(c, g, 0, 0);
topRight.paintIcon(c, g, width - sideSize * 2, 0);
topRight.paintIcon(c, g, width - topRight.getIconWidth(), 0);
bottomRight.paintIcon(c, g, width - bottomRight.getIconWidth(), height - bottomRight.getIconHeight());
bottomLeft.paintIcon(c, g, 0, height - bottomLeft.getIconHeight());
for (int _x = sideSize * 2; _x < width - sideSize * 2; _x ++) {
for (int _x = topLeft.getIconWidth(); _x < width - topRight.getIconWidth(); _x++) {
top.paintIcon(c, g, _x, 0);
}
for (int _x = bottomSize * 2; _x < width - bottomSize * 2; _x ++) {
for (int _x = bottomLeft.getIconWidth(); _x < width - bottomLeft.getIconWidth(); _x++) {
bottom.paintIcon(c, g, _x, height - bottomSize);
}
for (int _y = sideSize * 2; _y < height - bottomSize * 2; _y ++) {
for (int _y = topLeft.getIconHeight(); _y < height - bottomLeft.getIconHeight(); _y++) {
left.paintIcon(c, g, 0, _y);
}
for (int _y = topRight.getIconHeight(); _y < height - bottomRight.getIconHeight(); _y++) {
right.paintIcon(c, g, width - sideSize, _y);
}
bottomRight.paintIcon(c, g, width - bottomSize * 2, height - bottomSize * 2);
bottomLeft.paintIcon(c, g, 0, height - bottomSize * 2);
g.dispose();
return image;
}
@@ -111,7 +110,7 @@ public class ShadowBorderPainter {
int size = shadowSize;
final float w = source.getWidth(null);
final float h = source.getHeight(null);
float ratio = w /h;
float ratio = w / h;
float deltaX = size;
float deltaY = size / ratio;
@@ -157,5 +156,4 @@ public class ShadowBorderPainter {
return image;
}
}
}
@@ -42,7 +42,7 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
}
public static void actionPerformed(Project project, final boolean enableLink, final @Nullable UpdateSettingsConfigurable settingsConfigurable) {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Checking for updates", false) {
ProgressManager.getInstance().run(new Task.Modal(project, "Checking for updates", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final CheckForUpdateResult result = UpdateChecker.checkForUpdates(true);
@@ -19,6 +19,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.RepositoryHelper;
import com.intellij.ide.startup.StartupActionScriptManager;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
@@ -40,6 +41,7 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
/**
* @author anna
@@ -312,4 +314,12 @@ public class PluginDownloader {
public String getPluginVersion() {
return myPluginVersion;
}
public static PluginDownloader createDownloader(IdeaPluginDescriptor pluginDescriptor) throws UnsupportedEncodingException {
final BuildNumber buildNumber = ApplicationInfo.getInstance().getBuild();
final @NonNls String url = RepositoryHelper.DOWNLOAD_URL +
URLEncoder.encode(pluginDescriptor.getPluginId().getIdString(), "UTF8") +
"&build=" + buildNumber.asString();
return new PluginDownloader(pluginDescriptor.getPluginId().getIdString(), url, null, null, pluginDescriptor.getName());
}
}
@@ -16,6 +16,10 @@
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.RepositoryHelper;
import com.intellij.ide.reporter.ConnectionException;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.notification.Notification;
@@ -156,23 +160,56 @@ public final class UpdateChecker {
failed.add(host);
}
}
if (!failed.isEmpty()) {
final String failedMessage = IdeBundle.message("connection.failed.message", StringUtil.join(failed, ","));
if (showErrorDialog) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(failedMessage, IdeBundle.message("title.connection.error"));
}
});
}
else {
LOG.info(failedMessage);
final Map<String, IdeaPluginDescriptor> toUpdate = new HashMap<String, IdeaPluginDescriptor>();
final IdeaPluginDescriptor[] installedPlugins = PluginManager.getPlugins();
for (IdeaPluginDescriptor installedPlugin : installedPlugins) {
if (!installedPlugin.isBundled() && ((IdeaPluginDescriptorImpl)installedPlugin).isEnabled()) {
toUpdate.put(installedPlugin.getPluginId().getIdString(), installedPlugin);
}
}
if (!toUpdate.isEmpty()) {
try {
final ArrayList<IdeaPluginDescriptor> process = RepositoryHelper.process(null);
for (IdeaPluginDescriptor loadedPlugin : process) {
final String idString = loadedPlugin.getPluginId().getIdString();
final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
if (installedPlugin != null) {
if (StringUtil.compareVersionNumbers(loadedPlugin.getVersion(), installedPlugin.getVersion()) > 0) {
final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin);
if (downloader.prepareToInstall()) {
downloaded.add(downloader);
}
}
}
}
}
catch (Exception e) {
showErrorMessage(showErrorDialog, e.getMessage());
}
}
if (!failed.isEmpty()) {
showErrorMessage(showErrorDialog, IdeBundle.message("connection.failed.message", StringUtil.join(failed, ",")));
}
return downloaded.isEmpty() ? null : downloaded;
}
private static void showErrorMessage(boolean showErrorDialog, final String failedMessage) {
if (showErrorDialog) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(failedMessage, IdeBundle.message("title.connection.error"));
}
});
}
else {
LOG.info(failedMessage);
}
}
private static List<String> getPluginHosts(@Nullable UpdateSettingsConfigurable settingsConfigurable) {
final ArrayList<String> hosts = new ArrayList<String>();
if (settingsConfigurable != null) {
@@ -26,7 +26,6 @@ import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -130,7 +129,7 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
public void callback(ID self, String selector, ID toSelect) {
final ID chooser = invoke("NSOpenPanel", "openPanel");
invoke(chooser, "setPrompt:", Foundation.cfString("Choose"));
invoke(chooser, "setPrompt:", Foundation.nsString("Choose"));
invoke(chooser, "setCanChooseFiles:", myChooserDescriptor.isChooseFiles());
invoke(chooser, "setCanChooseDirectories:", myChooserDescriptor.isChooseFolders());
invoke(chooser, "setAllowsMultipleSelection:", myChooserDescriptor.isChooseMultiple());
@@ -152,8 +151,8 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
invoke(chooser, "setDelegate:", self);
Object directory = null;
Object file = null;
ID directory = null;
ID file = null;
final String toSelectPath = toSelect == null || toSelect.intValue() == 0 ? null : Foundation.toStringViaUTF8(toSelect);
final VirtualFile toSelectFile = toSelectPath == null ? null : LocalFileSystem.getInstance().findFileByPath(toSelectPath);
if (toSelectFile != null) {
@@ -161,8 +160,8 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
directory = toSelect;
}
else {
directory = Foundation.cfString(toSelectFile.getParent().getPath());
file = Foundation.cfString(toSelectFile.getName());
directory = Foundation.nsString(toSelectFile.getParent().getPath());
file = Foundation.nsString(toSelectFile.getName());
}
}
@@ -181,6 +180,14 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
if (focusedWindow != null) {
invoke(chooser, "beginSheetForDirectory:file:types:modalForWindow:modalDelegate:didEndSelector:contextInfo:",
directory, file, null, focusedWindow, self, Foundation.createSelector("openPanelDidEnd:returnCode:contextInfo:"), null);
if (directory != null) {
Foundation.cfRelease(directory);
}
if (file != null) {
Foundation.cfRelease(file);
}
}
}
}
@@ -265,7 +272,7 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
try {
final ID delegate = invoke(Foundation.getClass("NSOpenPanelDelegate_"), "new");
final Pointer select = toSelect == null ? null : Foundation.cfString(toSelect.getPath());
final ID select = toSelect == null ? null : Foundation.nsString(toSelect.getPath());
Foundation.cfRetain(delegate);
invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("showOpenPanel:"), select, false);
@@ -281,7 +288,7 @@ public class MacFileChooserDialogImpl implements MacFileChooserDialog {
try {
final ID delegate = invoke(Foundation.getClass("NSOpenPanelDelegate_"), "new");
final Pointer select = toSelect == null ? null : Foundation.cfString(toSelect.getPath());
final ID select = toSelect == null ? null : Foundation.nsString(toSelect.getPath());
Foundation.cfRetain(delegate);
invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("showOpenPanel:"), select, false);
@@ -177,18 +177,18 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable {
ID delegate = invoke(invoke("IdeaNSWindowDelegate" + v, "alloc"), "init");
invoke(notificationCenter, "addObserver:selector:name:object:", delegate,
Foundation.createSelector("windowDidEnterFullScreen:"),
Foundation.cfString("NSWindowDidEnterFullScreenNotification"), window);
Foundation.nsString("NSWindowDidEnterFullScreenNotification"), window);
//invoke(notificationCenter, "addObserver:selector:name:object:", delegate,
// Foundation.createSelector("windowDidExitFullScreen:"),
// Foundation.cfString("NSWindowDidExitFullScreenNotification"), window);
// Foundation.nsString("NSWindowDidExitFullScreenNotification"), window);
} else {
// toggle toolbar
String className = "IdeaToolbar" + v;
final ID ownToolbar = Foundation.registerObjcClass(Foundation.getClass("NSToolbar"), className);
Foundation.registerObjcClassPair(ownToolbar);
ID toolbar = invoke(invoke(className, "alloc"), "initWithIdentifier:", Foundation.cfString(className));
ID toolbar = invoke(invoke(className, "alloc"), "initWithIdentifier:", Foundation.nsString(className));
Foundation.cfRetain(toolbar);
invoke(toolbar, "setVisible:", 0); // hide native toolbar by default
@@ -158,7 +158,7 @@ public class MacMessagesImpl extends MacMessages {
// it is impossible to override ESCAPE key behavior -> key should be named "Cancel" to be bound to ESC
//if (!alternateExist) {
//invoke(invoke(invoke(alert, "buttons"), "objectAtIndex:", 1), "setKeyEquivalent:", cfString("\\e"));
//invoke(invoke(invoke(alert, "buttons"), "objectAtIndex:", 1), "setKeyEquivalent:", nsString("\\e"));
//}
String doNotAsk = toStringViaUTF8(doNotAskText);
@@ -263,19 +263,21 @@ public class MacMessagesImpl extends MacMessages {
final ID buttonsArray = invoke("NSMutableArray", "array");
for (String s : buttons) {
invoke(buttonsArray, "addObject:", cfString(UIUtil.removeMnemonic(s)));
ID s1 = nsString(UIUtil.removeMnemonic(s));
invoke(buttonsArray, "addObject:", s);
cfRelease(s1);
}
ID paramsArray = invoke("NSArray", "arrayWithObjects:", cfString(title),
ID paramsArray = invoke("NSArray", "arrayWithObjects:", nsString(title),
// replace % -> %% to avoid formatted parameters (causes SIGTERM)
cfString(StringUtil.stripHtml(message, true).replace("%", "%%")),
focusedWindow, cfString(fakeTitle), cfString(errorStyle ? "error" : "-1"),
cfString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
nsString(StringUtil.stripHtml(message, true).replace("%", "%%")),
focusedWindow, nsString(fakeTitle), nsString(errorStyle ? "error" : "-1"),
nsString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
// TODO: state=!doNotAsk.shouldBeShown()
? "-1"
: doNotAskDialogOption.getDoNotShowMessage()),
cfString(Integer.toString(defaultOptionIndex)),
cfString(Integer.toString(focusedOptionIndex)), buttonsArray, null);
nsString(Integer.toString(defaultOptionIndex)),
nsString(Integer.toString(focusedOptionIndex)), buttonsArray, null);
IdeFocusManager.getGlobalInstance().setTypeaheadEnabled(false);
@@ -427,13 +429,13 @@ public class MacMessagesImpl extends MacMessages {
fakeTitle = String.format("MacSheetDialog-%d", delegate.intValue());
ID paramsArray = invoke("NSArray", "arrayWithObjects:", cfString(title), cfString(UIUtil.removeMnemonic(defaultText)),
cfString(otherText == null ? "-1" : UIUtil.removeMnemonic(otherText)),
cfString(alternateText == null ? "-1" : UIUtil.removeMnemonic(alternateText)),
ID paramsArray = invoke("NSArray", "arrayWithObjects:", nsString(title), nsString(UIUtil.removeMnemonic(defaultText)),
nsString(otherText == null ? "-1" : UIUtil.removeMnemonic(otherText)),
nsString(alternateText == null ? "-1" : UIUtil.removeMnemonic(alternateText)),
// replace % -> %% to avoid formatted parameters (causes SIGTERM)
cfString(StringUtil.stripHtml(message, true).replace("%", "%%")),
focusedWindow, cfString(fakeTitle), cfString(errorStyle ? "error" : "-1"),
cfString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
nsString(StringUtil.stripHtml(message, true).replace("%", "%%")),
focusedWindow, nsString(fakeTitle), nsString(errorStyle ? "error" : "-1"),
nsString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
// TODO: state=!doNotAsk.shouldBeShown()
? "-1"
: doNotAskDialogOption.getDoNotShowMessage()), null);
@@ -55,7 +55,7 @@ public class Growl {
new Object[]{myProductName, applicationIcon, defaultNotifications, allNotifications});
final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter");
final Object notificationName = Foundation.cfString(GROWL_APPLICATION_REGISTRATION_NOTIFICATION);
final Object notificationName = Foundation.nsString(GROWL_APPLICATION_REGISTRATION_NOTIFICATION);
invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, userDict, true);
invoke(autoReleasePool, "release");
}
@@ -66,7 +66,7 @@ public class Growl {
GROWL_NOTIFICATION_NAME, GROWL_NOTIFICATION_TITLE, GROWL_NOTIFICATION_DESCRIPTION, GROWL_APP_NAME},
new Object[]{notification, title, description, myProductName});
final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter");
final Object notificationName = Foundation.cfString(GROWL_NOTIFICATION);
final Object notificationName = Foundation.nsString(GROWL_NOTIFICATION);
invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, dict, true);
invoke(autoReleasePool, "release");
@@ -104,7 +104,7 @@ public class Growl {
if (o instanceof Pointer || o instanceof ID) {
return o;
} else if (o instanceof String) {
return Foundation.cfString((String) o);
return Foundation.nsString((String)o);
} else {
throw new IllegalArgumentException("Unsupported type! " + o.getClass());
}
@@ -28,11 +28,10 @@ import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.List;
import static java.awt.event.KeyEvent.KEY_PRESSED;
import static java.awt.event.KeyEvent.VK_ENTER;
import static java.awt.event.KeyEvent.VK_TAB;
import static java.awt.event.KeyEvent.*;
/**
* @author Konstantin Bulenkov
@@ -56,8 +55,11 @@ public abstract class JBListTable extends JPanel {
}
};
mainTable = new JBTable(model) {
private MouseEvent myMouseEvent;
@Override
protected void processKeyEvent(KeyEvent e) {
myMouseEvent = null;
if (e.isAltDown()) return;
//todo[kb] JBTabsImpl breaks focus traversal policy. Need a workaround here
if (e.getKeyCode() == VK_TAB) {
@@ -76,6 +78,12 @@ public abstract class JBListTable extends JPanel {
super.processKeyEvent(e);
}
@Override
protected void processMouseEvent(MouseEvent e) {
myMouseEvent = e;
super.processMouseEvent(e);
}
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
return new DefaultTableCellRenderer() {
@@ -144,6 +152,7 @@ public abstract class JBListTable extends JPanel {
public TableCellEditor getCellEditor(final int row, int column) {
final JBTableRowEditor editor = getRowEditor(row);
if (editor != null) {
editor.setMouseEvent(myMouseEvent);
editor.prepareEditor(t, row);
installPaddingAndBordersForEditors(editor);
editor.setFocusCycleRoot(true);
@@ -16,13 +16,17 @@
package com.intellij.util.ui.table;
import com.intellij.openapi.wm.IdeFocusManager;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.MouseEvent;
/**
* @author Konstantin Bulenkov
*/
public abstract class JBTableRowEditor extends JPanel {
private MouseEvent myMouseEvent;
@Override
public void addNotify() {
super.addNotify();
@@ -32,6 +36,15 @@ public abstract class JBTableRowEditor extends JPanel {
}
}
@Nullable
public final MouseEvent getMouseEvent() {
return myMouseEvent;
}
public final void setMouseEvent(@Nullable MouseEvent e) {
myMouseEvent = e;
}
public abstract void prepareEditor(JTable table, int row);
public abstract JBTableRow getValue();
public abstract JComponent getPreferredFocusedComponent();
@@ -148,3 +148,5 @@ ide.enable.toolwindow.stack=false
change.signature.awesome.mode=true
change.signature.awesome.mode.description=Enables list view for change signature
navbar.is.decorated=false
navbar.is.decorated.description=NavBar with decorations
@@ -389,6 +389,7 @@
</action>
<action id="GotoRelated">
<keyboard-shortcut first-keystroke="control meta UP"/>
<keyboard-shortcut first-keystroke="alt meta UP"/>
</action>
<action id="QuickImplementations">
<keyboard-shortcut first-keystroke="alt SPACE"/>
@@ -18,7 +18,9 @@ package com.intellij.openapi.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TextRange implements Segment{
import java.io.Serializable;
public class TextRange implements Segment, Serializable {
public static final TextRange EMPTY_RANGE = new TextRange(0,0);
private final int myStartOffset;
private final int myEndOffset;
@@ -128,7 +128,7 @@ public class Foundation {
public static boolean isPackageAtPath(@NotNull final String path) {
final ID workspace = invoke("NSWorkspace", "sharedWorkspace");
final ID result = invoke(workspace, createSelector("isFilePackageAtPath:"), cfString(path));
final ID result = invoke(workspace, createSelector("isFilePackageAtPath:"), nsString(path));
return result.intValue() == 1;
}
@@ -138,18 +138,17 @@ public class Foundation {
return isPackageAtPath(file.getPath());
}
/**
* Return a CFString as an ID, toll-free bridged to NSString.
* <p/>
* Note that the returned string must be freed with {@link #cfRelease(ID)}.
*/
public static Pointer cfString(String s) {
public static ID nsString(String s) {
// Use a byte[] rather than letting jna do the String -> char* marshalling itself.
// Turns out about 10% quicker for long strings.
try {
if (s.length() == 0) {
return invoke("NSString", "string");
}
byte[] utf16Bytes = s.getBytes("UTF-16LE");
return myFoundationLibrary.CFStringCreateWithBytes(null, utf16Bytes, utf16Bytes.length, FoundationLibrary.kCFStringEncodingUTF16LE,
(byte)0); /* kTextEncodingUnicodeDefault + kUnicodeUTF16LEFormat */
return invoke(invoke("NSString", "alloc"), "initWithBytes:length:encoding:", utf16Bytes, utf16Bytes.length,
myFoundationLibrary.CFStringConvertEncodingToNSStringEncoding(FoundationLibrary.kCFStringEncodingUTF16LE));
}
catch (UnsupportedEncodingException x) {
throw new RuntimeException(x);
@@ -179,7 +178,7 @@ public class Foundation {
public static long getEncodingCode(@Nullable String encodingName) {
if (StringUtil.isEmptyOrSpaces(encodingName)) return -1;
Pointer converted = cfString(encodingName);
ID converted = nsString(encodingName);
int cfEncoding = myFoundationLibrary.CFStringConvertIANACharSetNameToEncoding(converted);
if (cfEncoding == FoundationLibrary.kCFStringEncodingInvalidId) return -1;
@@ -190,8 +189,10 @@ public class Foundation {
myFoundationLibrary.CFRetain(id);
}
public static void cfRelease(ID id) {
myFoundationLibrary.CFRelease(id);
public static void cfRelease(ID... id) {
for (ID id1 : id) {
myFoundationLibrary.CFRelease(id1);
}
}
public static boolean isMainThread() {
@@ -223,7 +224,7 @@ public class Foundation {
final ID ideaRunnable = getClass("IdeaRunnable");
final ID runnableObject = invoke(invoke(ideaRunnable, "alloc"), "init");
invoke(runnableObject, "performSelectorOnMainThread:withObject:waitUntilDone:", createSelector("run:"),
cfString(String.valueOf(ourCurrentRunnableCount)), Boolean.valueOf(waitUntilDone));
nsString(String.valueOf(ourCurrentRunnableCount)), Boolean.valueOf(waitUntilDone));
invoke(runnableObject, "release");
}
@@ -30,14 +30,14 @@ public interface FoundationLibrary extends Library {
ID objc_allocateClassPair(ID supercls, String name, int extraBytes);
void objc_registerClassPair(ID cls);
Pointer CFStringCreateWithBytes(Pointer allocator, byte[] bytes, int byteCount, int encoding, byte isExternalRepresentation);
ID CFStringCreateWithBytes(Pointer allocator, byte[] bytes, int byteCount, int encoding, byte isExternalRepresentation);
byte CFStringGetCString(ID theString, byte[] buffer, int bufferSize, int encoding);
int CFStringGetLength(ID theString);
int CFStringConvertNSStringEncodingToEncoding(long nsEncoding);
ID CFStringConvertEncodingToIANACharSetName(int cfEncoding);
int CFStringConvertIANACharSetNameToEncoding(Pointer encodingName);
int CFStringConvertIANACharSetNameToEncoding(ID encodingName);
long CFStringConvertEncodingToNSStringEncoding(int cfEncoding);
void CFRetain(ID cfTypeRef);
@@ -19,7 +19,9 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Pair;
import com.intellij.util.*;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
@@ -275,6 +277,22 @@ public class ContainerUtil {
return set;
}
@NotNull
public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull T[] collection, @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
return map2Map(Arrays.asList(collection), mapper);
}
@NotNull
public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull Collection<? extends T> collection,
@NotNull Function<T, Pair<KEY, VALUE>> mapper) {
final Map<KEY, VALUE> set = new THashMap<KEY, VALUE>(collection.size());
for (T t : collection) {
Pair<KEY, VALUE> pair = mapper.fun(t);
set.put(pair.first, pair.second);
}
return set;
}
@NotNull
public static <T> Object[] map2Array(@NotNull T[] array, @NotNull Function<T, Object> mapper) {
return map2Array(array, Object.class, mapper);
@@ -23,12 +23,13 @@ import com.intellij.util.Processor;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class MostlySingularMultiMap<K, V> {
public class MostlySingularMultiMap<K, V> implements Serializable {
private final Map<K, Object> myMap = new THashMap<K, Object>();
public void add(K key, V value) {
@@ -1623,9 +1623,8 @@ increment.decrement.used.as.expression.quickfix=Extract ''{0}'' to separate stat
ignore.classes.in.hierarchy.column.name=Ignore subclasses of
overly.strong.type.cast.ignore.in.matching.instanceof.option=Ignore casts with a matching instanceof expression
return.of.collection.field.quickfix=Replace with ''{0}''
access.to.non.thread.safe.static.field.from.instance.display.name=Access to non thread-safe static field from instance
access.to.non.thread.safe.static.field.from.instance.field.problem.descriptor=Access to static ''{0}'' field <code>#ref</code> from instance field initializer #loc
access.to.non.thread.safe.static.field.from.instance.method.problem.descriptor=Access to static ''{0}'' field <code>#ref</code> from instance method #loc
access.to.non.thread.safe.static.field.from.instance.display.name=Non thread-safe static field access
access.to.non.thread.safe.static.field.from.instance.field.problem.descriptor=Access to non thread-safe static field <code>#ref</code> of type ''{0}'' #loc
access.to.non.thread.safe.static.field.from.instance.option.title=Non thread safe classes
access.to.non.thread.safe.static.field.from.instance.class.chooser.title=Choose non thread safe class
non.thread.safe.types.column.name=Non Thread-safe Types
@@ -21,6 +21,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class IgnoredJUnitTestInspection extends BaseInspection {
@@ -62,7 +63,6 @@ public class IgnoredJUnitTestInspection extends BaseInspection {
PsiModifierListOwner.class);
if (!(modifierListOwner instanceof PsiClass ||
modifierListOwner instanceof PsiMethod)) {
System.out.println(1);
return;
}
final PsiJavaCodeReferenceElement nameReferenceElement =
@@ -72,11 +72,10 @@ public class IgnoredJUnitTestInspection extends BaseInspection {
}
final PsiElement target = nameReferenceElement.resolve();
if (!(target instanceof PsiClass)) {
System.out.println(2);
return;
}
final PsiClass aClass = (PsiClass) target;
final String qualifiedName = aClass.getQualifiedName();
@NonNls final String qualifiedName = aClass.getQualifiedName();
if (!"org.junit.Ignore".equals(qualifiedName)) {
return;
}
@@ -196,18 +196,18 @@ public class JUnit4AnnotatedMethodInJUnit3TestCaseInspection extends
@Override
public void visitMethod(PsiMethod method) {
super.visitMethod(method);
if (AnnotationUtil.isAnnotated(method, IGNORE, false) && method.getName().startsWith("test")) {
registerMethodError(method, method);
return;
}
if (!TestUtils.isJUnit4TestMethod(method)) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return;
return;
}
if (!TestUtils.isJUnitTestClass(containingClass)) {
return;
}
if (AnnotationUtil.isAnnotated(method, IGNORE, false) && method.getName().startsWith("test")) {
registerMethodError(method, method);
return;
}
if (!TestUtils.isJUnit4TestMethod(method)) {
return;
}
final String className = containingClass.getName();
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2010 Bas Leijdekkers
* Copyright 2008-2011 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -95,16 +95,30 @@ public class CollectionsFieldAccessReplaceableByMethodCallInspection
for (int i = 0, parameterTypesLength = parameterTypes.length;
i < parameterTypesLength; i++) {
final PsiType parameterType = parameterTypes[i];
if (!parameterType.equalsToText(
CommonClassNames.JAVA_LANG_OBJECT)) {
useTypeParameter = true;
if (parameterType instanceof PsiWildcardType) {
final PsiWildcardType wildcardType =
(PsiWildcardType)parameterType;
final PsiType bound = wildcardType.getBound();
if (bound != null) {
if (!bound.equalsToText(
CommonClassNames.JAVA_LANG_OBJECT)) {
useTypeParameter = true;
}
canonicalTexts[i] = bound.getCanonicalText();
} else {
canonicalTexts[i] = CommonClassNames.JAVA_LANG_OBJECT;
}
} else {
if (!parameterType.equalsToText(
CommonClassNames.JAVA_LANG_OBJECT)) {
useTypeParameter = true;
}
canonicalTexts[i] = parameterType.getCanonicalText();
}
canonicalTexts[i] = parameterType.getCanonicalText();
}
if (useTypeParameter) {
return "Collections.<" + StringUtil.join(canonicalTexts, ",") +
'>' +
getCollectionsMethodCallText(referenceName);
'>' + getCollectionsMethodCallText(referenceName);
} else {
return getUntypedCollectionsMethodCallText(referenceName);
}
@@ -55,6 +55,12 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspection
}
}
@NotNull
@Override
public String getID() {
return "AccessToNonThreadSafeStaticField";
}
@Override
@Nls
@NotNull
@@ -66,16 +72,11 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspection
@Override
@NotNull
protected String buildErrorString(Object... infos) {
if (infos[0] instanceof PsiMethod) {
return InspectionGadgetsBundle.message(
"access.to.non.thread.safe.static.field.from.instance.method.problem.descriptor",
infos[1]);
}
return InspectionGadgetsBundle.message(
"access.to.non.thread.safe.static.field.from.instance.field.problem.descriptor",
infos[1]);
infos[0]);
}
@Override
@Nullable
public JComponent createOptionsPanel() {
@@ -104,9 +105,6 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspection
if (parent == null) {
return;
}
if (parent.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
if (parent instanceof PsiMethod ||
parent instanceof PsiClassInitializer) {
if (parent.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
@@ -140,7 +138,7 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspection
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
registerError(expression, parent, className);
registerError(expression, className);
}
}
}
@@ -111,7 +111,7 @@ android.project.contains.errors.error=The project contains errors
android.export.package.existing.keystore.label=&Use existing keystore
android.export.package.new.keystore.label=&Create new keystore
android.export.package.keystore.location.label=&Location:
android.password.label=&Password:
android.password.label=Pa&ssword:
android.confirm.password.label=&Confirm:
android.export.package.passwords.not.match.error=Passwords do not match
android.export.package.specify.keystore.location.error=Please specify keystore location
@@ -129,7 +129,7 @@ android.export.package.key.validity.label=&Validity (years):
android.export.package.key.certificate.name.label=&First and Last Name:
android.export.package.organization.unit.label=&Organizational Unit:
android.export.package.city.label=City or &Locality:
android.export.package.state.label=&State or Province:
android.export.package.state.label=S&tate or Province:
android.export.package.country.code.label=Country Code (&XX):
android.export.package.specify.key.alias.error=Please specify key alias
android.export.package.specify.certificate.field.error=At least one Certificate issuer field is required to be non-empty
@@ -222,10 +222,10 @@ android.facet.compiler.settings.manifest.title=Manifest
android.facet.settings.compiler.manifest.from.structure=Use AndroidManifest.xml file specified at "Structure" section
android.facet.settings.compiler.manifest.use.custom=Use custom manifest file:
android.facet.settings.compile.resources.by.ide=&Compile resources by IDE
android.keystore.password.label=&Password:
android.keystore.password.label=Pa&ssword:
android.keystore.confirm.password.label=C&onfirm:
android.export.package.new.key.alias.label=&Alias:
android.key.password.label=&Password:
android.key.password.label=Pa&ssword:
android.cannot.run.library.project.error=The module cannot be Android library project
android.compilation.error.specify.platform=Android SDK is not specified for module {0}
android.compilation.error.manifest.not.found=AndroidManifest.xml file not found. Please, check Android facet settings.
@@ -140,14 +140,18 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase {
protected boolean isAvailable(DataContext context) {
if (!super.isAvailable(context)) return false;
final PsiElement element = (PsiElement)context.getData(DataKeys.PSI_ELEMENT.getName());
if (element instanceof PsiDirectory) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
return ResourceManager.isResourceSubdirectory((PsiDirectory)element, myResourceType);
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
PsiElement e = element;
while (e != null) {
if (e instanceof PsiDirectory && ResourceManager.isResourceSubdirectory((PsiDirectory)e, myResourceType)) {
return true;
}
e = e.getParent();
}
});
}
return false;
return false;
}
});
}
@Override
@@ -1,9 +1,12 @@
package org.jetbrains.android.uipreview;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.HyperlinkLabel;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.AsyncProcessIcon;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -15,7 +18,7 @@
/**
* @author Eugene.Kudelevsky
*/
public class AndroidLayoutPreviewPanel extends JPanel {
public class AndroidLayoutPreviewPanel extends JPanel implements Disposable {
private static final double EPS = 0.0000001;
private static final double MAX_ZOOM_FACTOR = 2.0;
private static final double ZOOM_STEP = 1.25;
@@ -23,7 +26,6 @@ public class AndroidLayoutPreviewPanel extends JPanel {
private RenderingErrorMessage myErrorMessage;
private String myWarnMessage;
private BufferedImage myImage;
private JBLabel myProgressLabel;
private final HyperlinkLabel myErrorLabel = new HyperlinkLabel("", Color.BLUE, getBackground(), Color.BLUE);
@@ -46,6 +48,8 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
};
private AsyncProcessIcon myProgressIcon;
public AndroidLayoutPreviewPanel() {
super(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true, true));
setBackground(Color.WHITE);
@@ -62,12 +66,18 @@ public class AndroidLayoutPreviewPanel extends JPanel {
});
myErrorLabel.setOpaque(false);
myProgressLabel = new JBLabel("Rendering...");
myProgressLabel.setIcon(Messages.getInformationIcon());
myProgressLabel.setVisible(false);
final JPanel progressPanel = new JPanel();
progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.X_AXIS));
myProgressIcon = new AsyncProcessIcon("Android layout rendering");
Disposer.register(this, myProgressIcon);
progressPanel.add(Box.createHorizontalGlue());
progressPanel.add(myProgressIcon);
progressPanel.add(new JBLabel(" "));
progressPanel.setOpaque(false);
myProgressIcon.setVisible(false);
add(progressPanel);
add(myErrorLabel);
add(myProgressLabel);
add(new MyImagePanelWrapper());
}
@@ -77,14 +87,13 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
public void showProgress() {
myProgressLabel.setVisible(true);
myErrorLabel.setVisible(false);
myImagePanel.setVisible(false);
myProgressIcon.setVisible(true);
myProgressIcon.resume();
}
@Nullable
public BufferedImage getImage() {
return myImage;
public void hideProgress() {
myProgressIcon.suspend();
myProgressIcon.setVisible(false);
}
private void doRevalidate() {
@@ -102,7 +111,6 @@ public class AndroidLayoutPreviewPanel extends JPanel {
}
public void update() {
myProgressLabel.setVisible(false);
myImagePanel.setVisible(true);
if (myErrorMessage != null) {
myErrorLabel.setHyperlinkText(myErrorMessage.myBeforeLinkText,
@@ -218,6 +226,10 @@ public class AndroidLayoutPreviewPanel extends JPanel {
return myZoomToFit;
}
@Override
public void dispose() {
}
private class MyImagePanelWrapper extends JLayeredPane {
public MyImagePanelWrapper() {
add(myImagePanel);
@@ -5,10 +5,10 @@ import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.configuration.LanguageQualifier;
import com.android.ide.common.resources.configuration.RegionQualifier;
import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
import com.android.resources.UiMode;
import com.android.resources.NightMode;
import com.android.resources.ResourceType;
import com.android.resources.ScreenSize;
import com.android.resources.UiMode;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.intellij.ide.ui.ListCellRendererWrapper;
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -97,6 +98,8 @@ class AndroidLayoutPreviewToolWindowForm implements Disposable {
private final AndroidLayoutPreviewToolWindowSettings mySettings;
public AndroidLayoutPreviewToolWindowForm(final Project project, AndroidLayoutPreviewToolWindowManager toolWindowManager) {
Disposer.register(this, myPreviewPanel);
myToolWindowManager = toolWindowManager;
mySettings = AndroidLayoutPreviewToolWindowSettings.getInstance(project);
@@ -5,7 +5,6 @@ import com.android.sdklib.IAndroidTarget;
import com.intellij.ProjectTopics;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -13,6 +12,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootEvent;
@@ -35,6 +36,7 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.containers.HashMap;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.android.dom.layout.LayoutDomFileDescription;
@@ -53,6 +55,8 @@ import org.jetbrains.annotations.Nullable;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -242,15 +246,12 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
myRenderingQueue.queue(new Update("render") {
@Override
public void run() {
if (showProgress || myToolWindowForm.getPreviewPanel().getImage() == null) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
myToolWindowForm.getPreviewPanel().showProgress();
}
}, ModalityState.defaultModalityState());
}
doRender(facet, layoutXmlText);
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
doRender(facet, layoutXmlText);
}
}, new MyProgressIndicator());
}
@Override
@@ -355,7 +356,7 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
}
});
}
private void showStackStace(@NotNull Throwable t) {
final String stackTrace = getStackTrace(t);
final DialogWrapper wrapper = new DialogWrapper(myProject, false) {
@@ -372,11 +373,11 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
panel.add(ScrollPaneFactory.createScrollPane(textArea));
return panel;
}
};
};
wrapper.setTitle("Stack trace");
wrapper.show();
}
@NotNull
private static String getStackTrace(@NotNull Throwable t) {
final StringWriter stringWriter = new StringWriter();
@@ -517,4 +518,43 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
processFileEditorChange(layoutXmlEditor);
}
}
private class MyProgressIndicator extends ProgressIndicatorBase {
private final Object myLock = new Object();
@Override
public void start() {
super.start();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final Timer timer = UIUtil.createNamedTimer("Android rendering progress timer", 1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
synchronized (myLock) {
if (isRunning()) {
myToolWindowForm.getPreviewPanel().showProgress();
}
}
}
});
timer.setRepeats(false);
timer.start();
}
});
}
@Override
public void stop() {
synchronized (myLock) {
super.stop();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myToolWindowForm.getPreviewPanel().hideProgress();
}
});
}
}
}
}
+5
View File
@@ -28,6 +28,11 @@
<add-to-group group-id="ProjectViewPopupMenu"/>
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="Github.Create.Gist" class="org.jetbrains.plugins.github.GithubCreateGistAction">
<add-to-group group-id="EditorPopupMenu"/>
<add-to-group group-id="ProjectViewPopupMenu"/>
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="Github.Rebase.Internal" class="org.jetbrains.plugins.github.GithubRebase"/>
</actions>
</idea-plugin>
@@ -0,0 +1,164 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.github;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.jetbrains.plugins.github.ui.GitHubCreateGistDialog;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
import javax.swing.*;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author oleg
* @date 9/27/11
*/
public class GithubCreateGistAction extends DumbAwareAction {
public static final Icon ICON = IconLoader.getIcon("/icons/github.png");
private static final Logger LOG = Logger.getInstance(GithubCreateGistAction.class);
protected GithubCreateGistAction() {
super("Create gist", "Create github gist", ICON);
}
@Override
public void update(final AnActionEvent e) {
final long startTime = System.nanoTime();
try {
final Project project = e.getData(PlatformDataKeys.PROJECT);
if (project == null || project.isDefault()) {
e.getPresentation().setVisible(false);
e.getPresentation().setEnabled(false);
return;
}
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null){
e.getPresentation().setVisible(true);
e.getPresentation().setEnabled(true);
return;
}
e.getPresentation().setVisible(false);
e.getPresentation().setEnabled(false);
}
finally {
if (LOG.isDebugEnabled()) {
LOG.debug("GithubCreateGistAction#update finished in: " + (System.nanoTime() - startTime) / 10e6 + "ms");
}
}
}
@Override
public void actionPerformed(final AnActionEvent e) {
final Project project = e.getData(PlatformDataKeys.PROJECT);
if (project == null || project.isDefault()) {
return;
}
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor == null){
return;
}
final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE);
if (file == null) {
return;
}
final boolean useGitHubAccount;
if (!GithubUtil.checkCredentials(project)) {
final GithubLoginDialog dialog = new GithubLoginDialog(project);
dialog.show();
useGitHubAccount = GithubUtil.checkCredentials(project);
} else {
useGitHubAccount = true;
}
// Ask for description and other params
final GitHubCreateGistDialog dialog = new GitHubCreateGistDialog(project, useGitHubAccount);
dialog.show();
if (!dialog.isOK()){
return;
}
final GithubSettings settings = GithubSettings.getInstance();
final String password = settings.getPassword();
final Ref<String> url = new Ref<String>();
final String description = dialog.getDescription();
final boolean isPrivate = dialog.isPrivate();
final boolean anonymous = dialog.isAnonimous();
final boolean openInBrowser = dialog.isOpenInBrowser();
// Text
final SelectionModel selectionModel = editor.getSelectionModel();
final String text = selectionModel.hasSelection() ? selectionModel.getSelectedText() : editor.getDocument().getText();
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
@Override
public void run() {
final HttpClient client = anonymous ? GithubUtil.getHttpClient(null, null) : GithubUtil.getHttpClient(settings.getLogin(), password);
client.getParams().setContentCharset("UTF-8");
final PostMethod method = new PostMethod("https://gist.github.com/gists");
method.addParameters(new NameValuePair[]{
new NameValuePair("description", description),
new NameValuePair("file_ext[gistfile1]", "." + file.getExtension()),
new NameValuePair("file_name[gistfile1]", file.getNameWithoutExtension()),
new NameValuePair("file_contents[gistfile1]", text)
});
if (isPrivate){
method.addParameter("action_button", "private");
}
try {
client.executeMethod(method);
final String responce = method.getResponseBodyAsString();
// TODO[oleg] fix it when github API v3 becomes public
// http://developer.github.com/v3/gists/
final Matcher matcher = Pattern.compile("\\d+").matcher(responce);
matcher.find();
url.set("https://gist.github.com/" + matcher.group());
}
catch (IOException e1) {
LOG.error("Failed to create gist: " + e1);
return;
}
finally {
method.releaseConnection();
}
}
}, "Communicating With GitHub", false, project);
if (url.isNull()){
return;
}
if (openInBrowser) {
BrowserUtil.launchBrowser(url.get());
} else {
Messages.showInfoMessage(project, "Your gist url: " + url.get(), "Gist Created Successfully");
}
}
}
@@ -97,7 +97,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction {
// Check that given repository is properly configured git repository
final GitRemote githubRemote = GithubUtil.getGithubBoundRepository(project);
final GitRemote githubRemote = GithubUtil.findGitHubRemoteBranch(project, project.getBaseDir());
if (githubRemote == null) {
Messages.showErrorDialog(project, "Configured github repository is not found", CANNOT_OPEN_IN_BROWSER);
return;
@@ -92,12 +92,14 @@ public class GithubRebaseAction extends DumbAwareAction {
@Override
public GitRemote compute() {
ProgressManager.getInstance().getProgressIndicator().setText("Reading branches information");
return GithubUtil.getGithubBoundRepository(project);
return GithubUtil.findGitHubRemoteBranch(project, project.getBaseDir());
}
});
final List<GitRemote> gitRemotes = GitRemote.list(project, root);
LOG.assertTrue(githubRemote != null);
if (githubRemote == null){
return;
}
final List<GitRemote> gitRemotes = GitRemote.list(project, root);
final String pushUrl = githubRemote.pushUrl();
final String login = GithubSettings.getInstance().getLogin();
final int index = pushUrl.lastIndexOf(login);
@@ -49,11 +49,18 @@ public class GithubSettings implements PersistentStateComponent<Element> {
private static final String GITHUB_SETTINGS_TAG = "GithubSettings";
private static final String LOGIN = "Login";
private static final String HOST = "Host";
private static final String ANONIMOUS_GIST = "Anonymous";
private static final String OPEN_IN_BROWSER_GIST = "OpenInBrowser";
private static final String PRIVATE_GIST = "Private";
private static final String GITHUB = "github.com";
private static final String GITHUB_SETTINGS_PASSWORD_KEY = "GITHUB_SETTINGS_PASSWORD_KEY";
private String myLogin;
private String myHost;
private boolean myAnonymousGist;
private boolean myOpenInBrowserGist = true;
private boolean myPrivateGist;
private static final Logger LOG = Logger.getInstance(GithubSettings.class.getName());
private boolean passwordChanged = false;
@@ -88,6 +95,9 @@ public class GithubSettings implements PersistentStateComponent<Element> {
final Element element = new Element(GITHUB_SETTINGS_TAG);
element.setAttribute(LOGIN, getLogin());
element.setAttribute(HOST, getHost());
element.setAttribute(ANONIMOUS_GIST, String.valueOf(isAnonymous()));
element.setAttribute(PRIVATE_GIST, String.valueOf(isPrivateGist()));
element.setAttribute(OPEN_IN_BROWSER_GIST, String.valueOf(isOpenInBrowserGist()));
return element;
}
@@ -96,6 +106,9 @@ public class GithubSettings implements PersistentStateComponent<Element> {
try {
setLogin(element.getAttributeValue(LOGIN));
setHost(element.getAttributeValue(HOST));
setAnonymousGist(Boolean.valueOf(element.getAttributeValue(ANONIMOUS_GIST)));
setPrivateGist(Boolean.valueOf(element.getAttributeValue(PRIVATE_GIST)));
setOpenInBrowserGist(Boolean.valueOf(element.getAttributeValue(OPEN_IN_BROWSER_GIST)));
}
catch (Exception e) {
LOG.error("Error happened while loading github settings: " + e);
@@ -147,6 +160,18 @@ public class GithubSettings implements PersistentStateComponent<Element> {
return myHost != null ? myHost : GITHUB;
}
public boolean isAnonymous() {
return myAnonymousGist;
}
public boolean isOpenInBrowserGist() {
return myOpenInBrowserGist;
}
public boolean isPrivateGist() {
return myPrivateGist;
}
public void setLogin(final String login) {
myLogin = login != null ? login : "";
}
@@ -168,4 +193,15 @@ public class GithubSettings implements PersistentStateComponent<Element> {
myHost = host != null ? host : GITHUB;
}
public void setAnonymousGist(final boolean anonymousGist) {
myAnonymousGist = anonymousGist;
}
public void setPrivateGist(final boolean privateGist) {
myPrivateGist = privateGist;
}
public void setOpenInBrowserGist(final boolean openInBrowserGist) {
myOpenInBrowserGist = openInBrowserGist;
}
}
@@ -125,7 +125,7 @@ public class GithubShareAction extends DumbAwareAction {
LOG.info("Creating GitHub repository");
final String escapedDescription = JDOMUtil.escapeText(description, true, true).replace("&#", "%");
GithubUtil.doREST(settings.getHost(), settings.getLogin(), settings.getPassword(),
"/repos/create?name=" + name + "&public=" + (isPrivate ? "0" : "1") + "&description=" + escapedDescription, true);
"/repos/create?name=" + name + "&public=" + (isPrivate ? "0" : "1") + "&description=" + escapedDescription, true).releaseConnection();
LOG.info("Successfully created GitHub repository");
}
catch (final Exception e1) {
@@ -28,7 +28,6 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.net.HttpConfigurable;
import git4idea.GitRemote;
import git4idea.GitUtil;
import git4idea.config.GitVcsApplicationSettings;
import git4idea.config.GitVersion;
import git4idea.i18n.GitBundle;
@@ -93,8 +92,9 @@ public class GithubUtil {
}
public static boolean testConnection(final String url, final String login, final String password) {
HttpMethod method = null;
try {
final HttpMethod method = doREST(url, login, password, "/user/show/" + login, false);
method = doREST(url, login, password, "/user/show/" + login, false);
final InputStream stream = method.getResponseBodyAsStream();
final Element element = new SAXBuilder(false).build(stream).getRootElement();
if ("error".equals(element.getName())){
@@ -106,6 +106,11 @@ public class GithubUtil {
catch (Exception e) {
// Ignore
}
finally {
if (method!=null) {
method.releaseConnection();
}
}
return false;
}
@@ -118,7 +123,7 @@ public class GithubUtil {
return method;
}
public static HttpClient getHttpClient(final String login, final String password) {
public static HttpClient getHttpClient(@Nullable final String login, @Nullable final String password) {
final HttpClient client = new HttpClient();
// Configure proxySettings if it is required
final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
@@ -129,15 +134,18 @@ public class GithubUtil {
proxySettings.getPlainProxyPassword()));
}
}
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password));
if (login != null && password != null) {
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password));
}
return client;
}
public static List<RepositoryInfo> getAvailableRepos(final String url, final String login, final String password, final boolean ownOnly) {
HttpMethod method = null;
try {
final String request = (ownOnly ? "/repos/show/" : "/repos/watched/") + login;
final HttpMethod method = doREST(url, login, password, request, false);
method = doREST(url, login, password, request, false);
final InputStream stream = method.getResponseBodyAsStream();
final Element element = new SAXBuilder(false).build(stream).getRootElement();
if ("error".equals(element.getName())){
@@ -155,15 +163,21 @@ public class GithubUtil {
catch (Exception e) {
// ignore
}
finally {
if (method != null){
method.releaseConnection();
}
}
return Collections.emptyList();
}
@Nullable
public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String owner, final String name) {
HttpMethod method = null;
try {
final String request = "/repos/show/" + owner + "/" + name;
final HttpMethod method = doREST(url, login, password, request, false);
method = doREST(url, login, password, request, false);
final InputStream stream = method.getResponseBodyAsStream();
final Element element = new SAXBuilder(false).build(stream).getRootElement();
if ("error".equals(element.getName())){
@@ -175,13 +189,19 @@ public class GithubUtil {
catch (Exception e) {
// ignore
}
finally {
if (method != null){
method.releaseConnection();
}
}
return null;
}
public static boolean isPrivateRepoAllowed(final String url, final String login, final String password) {
HttpMethod method = null;
try {
final String request = "/user/show/" + login;
final HttpMethod method = doREST(url, login, password, request, false);
method = doREST(url, login, password, request, false);
final InputStream stream = method.getResponseBodyAsStream();
final Element element = new SAXBuilder(false).build(stream).getRootElement();
if ("error".equals(element.getName())){
@@ -196,6 +216,11 @@ public class GithubUtil {
catch (Exception e) {
// ignore
}
finally {
if (method != null){
method.releaseConnection();
}
}
return false;
}
@@ -295,17 +320,6 @@ public class GithubUtil {
}
}
@Nullable
public static GitRemote getGithubBoundRepository(final Project project){
final VirtualFile root = project.getBaseDir();
// Check if git is already initialized and presence of remote branch
final boolean gitDetected = GitUtil.isUnderGit(root);
if (!gitDetected) {
return null;
}
return findGitHubRemoteBranch(project, root);
}
@Nullable
public static GitRemote findGitHubRemoteBranch(final Project project, final VirtualFile root) {
// i.e. find origin which points on my github repo
@@ -0,0 +1,90 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.github.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.plugins.github.GithubSettings;
import javax.swing.*;
/**
* @author oleg
* @date 9/27/11
*/
public class GitHubCreateGistDialog extends DialogWrapper {
private final GitHubCreateGistPanel myGithubCreateGistPanel;
public GitHubCreateGistDialog(final Project project, final boolean canBePersonal) {
super(project, true);
myGithubCreateGistPanel = new GitHubCreateGistPanel();
myGithubCreateGistPanel.setCanBePersonal(canBePersonal);
// Use saved settings for controls
final GithubSettings settings = GithubSettings.getInstance();
if (canBePersonal){
myGithubCreateGistPanel.setAnonymous(settings.isAnonymous());
}
myGithubCreateGistPanel.setPrivate(settings.isPrivateGist());
myGithubCreateGistPanel.setOpenInBrowser(settings.isOpenInBrowserGist());
setTitle("Create Gist");
init();
}
protected Action[] createActions() {
return new Action[] {getOKAction(), getCancelAction(), getHelpAction()};
}
@Override
protected JComponent createCenterPanel() {
return myGithubCreateGistPanel.getPanel();
}
@Override
protected String getHelpId() {
return null;
}
@Override
protected void doOKAction() {
// Store settings
final GithubSettings settings = GithubSettings.getInstance();
settings.setAnonymousGist(myGithubCreateGistPanel.isAnonymous());
settings.setOpenInBrowserGist(myGithubCreateGistPanel.isOpenInBrowser());
settings.setPrivateGist(myGithubCreateGistPanel.isPrivate());
super.doOKAction();
}
@Override
public JComponent getPreferredFocusedComponent() {
return myGithubCreateGistPanel.getDescriptionTextArea();
}
public boolean isPrivate() {
return myGithubCreateGistPanel.isPrivate();
}
public boolean isAnonimous() {
return myGithubCreateGistPanel.isAnonymous();
}
public String getDescription() {
return myGithubCreateGistPanel.getDescriptionTextArea().getText();
}
public boolean isOpenInBrowser() {
return myGithubCreateGistPanel.isOpenInBrowser();
}
}
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.github.ui.GitHubCreateGistPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="1202b">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2ac57" class="javax.swing.JTextPane" binding="myNoticeTextPane">
<constraints>
<grid row="3" column="0" row-span="1" col-span="4" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<contentType value="text/html"/>
<editable value="false"/>
</properties>
<clientProperties>
<JEditorPane.honorDisplayProperties class="java.lang.Boolean" value="true"/>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
<component id="51bc1" class="javax.swing.JTextArea" binding="myDescriptionTextArea">
<constraints>
<grid row="1" column="0" row-span="1" col-span="4" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
</constraints>
<properties/>
<clientProperties>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
<component id="b0e4d" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Description:"/>
</properties>
</component>
<component id="5586a" class="javax.swing.JCheckBox" binding="myAnonymousCheckBox">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Anonimous"/>
</properties>
</component>
<hspacer id="192a4">
<constraints>
<grid row="2" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="3fe2f" class="javax.swing.JCheckBox" binding="myPrivateCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Private"/>
</properties>
</component>
<component id="9e4f3" class="javax.swing.JCheckBox" binding="myOpenInBrowserCheckBox">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Open in browser"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.github.ui;
import javax.swing.*;
/**
* @author oleg
* @date 9/27/11
*/
public class GitHubCreateGistPanel {
private JTextArea myDescriptionTextArea;
private JTextPane myNoticeTextPane;
private JCheckBox myPrivateCheckBox;
private JPanel myPanel;
private JCheckBox myAnonymousCheckBox;
private JCheckBox myOpenInBrowserCheckBox;
public GitHubCreateGistPanel() {
myDescriptionTextArea.setBorder(BorderFactory.createEtchedBorder());
}
public boolean isPrivate(){
return myPrivateCheckBox.isSelected();
}
public boolean isAnonymous(){
return myAnonymousCheckBox.isSelected();
}
public boolean isOpenInBrowser(){
return myOpenInBrowserCheckBox.isSelected();
}
public void setPrivate(final boolean isPrivate){
myPrivateCheckBox.setSelected(isPrivate);
}
public void setAnonymous(final boolean anonymous){
myAnonymousCheckBox.setSelected(anonymous);
}
public void setOpenInBrowser(final boolean openInBrowser) {
myOpenInBrowserCheckBox.setSelected(openInBrowser);
}
public JPanel getPanel() {
return myPanel;
}
public JTextArea getDescriptionTextArea() {
return myDescriptionTextArea;
}
public void setCanBePersonal(final boolean canBePersonal) {
if (!canBePersonal){
myAnonymousCheckBox.setEnabled(false);
myAnonymousCheckBox.setSelected(true);
myNoticeTextPane.setText("<html><body><b>Note</b> you must be logged in to github to create personal gists</body></html>");
}
}
}
@@ -57,7 +57,8 @@ public abstract class AbstractGradleDependency extends AbstractGradleEntity impl
public String toString() {
return "scope: " + getScope() + ", exported: " + isExported();
}
@NotNull
@Override
public GradleDependency clone() {
try {
@@ -99,8 +99,9 @@ public class GradleContentRoot extends AbstractGradleEntity {
return buffer.toString();
}
@NotNull
@Override
public GradleContentRoot clone() {
public GradleContentRoot clone(@NotNull GradleEntityCloneContext context) {
GradleContentRoot result = new GradleContentRoot(getRootPath());
for (Map.Entry<SourceType, Collection<String>> entry : myData.entrySet()) {
for (String path : entry.getValue()) {
@@ -16,5 +16,6 @@ public interface GradleDependency extends GradleEntity {
@NotNull
DependencyScope getScope();
GradleDependency clone();
@NotNull
GradleDependency clone(@NotNull GradleEntityCloneContext context);
}
@@ -15,7 +15,7 @@ import java.io.Serializable;
* @author Denis Zhdanov
* @since 8/12/11 12:50 PM
*/
public interface GradleEntity extends Cloneable, Serializable {
public interface GradleEntity extends Serializable {
/**
* Follows contract of {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
@@ -25,4 +25,7 @@ public interface GradleEntity extends Cloneable, Serializable {
void addPropertyChangeListener(@NotNull PropertyChangeListener listener);
void invite(@NotNull GradleEntityVisitor visitor);
@NotNull
GradleEntity clone(@NotNull GradleEntityCloneContext context);
}
@@ -0,0 +1,44 @@
package org.jetbrains.plugins.gradle.importing.model;
import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* We need to be able to perform cloning of gradle entities. However, there is a possible case that particular entity
* encapsulates graph of other entities. For example, {@link GradleModule} has a number of
* {@link GradleModule#getDependencies() dependencies} where those dependencies can reference other modules that, in turn, also
* have dependencies.
* <p/>
* The problem is that we need to ensure that particular entity is shared within a single entities graph (e.g. there should
* be a single shared instance of {@link GradleModule gradle module} after cloning). That's why we need some place to serve
* as a cache during cloning. This class serves that purpose.
*
* @author Denis Zhdanov
* @since 9/28/11 12:36 PM
*/
public class GradleEntityCloneContext {
private final Map<GradleLibrary, GradleLibrary> myLibraries = new HashMap<GradleLibrary, GradleLibrary>();
private final Map<GradleModule, GradleModule> myModules = new HashMap<GradleModule, GradleModule>();
@Nullable
public GradleLibrary getLibrary(@NotNull GradleLibrary library) {
return myLibraries.get(library);
}
public void store(@NotNull GradleLibrary key, @NotNull GradleLibrary value) {
myLibraries.put(key, value);
}
@Nullable
public GradleModule getModule(@NotNull GradleModule module) {
return myModules.get(module);
}
public void store(@NotNull GradleModule key, @NotNull GradleModule value) {
myModules.put(key, value);
}
}

Some files were not shown because too many files have changed in this diff Show More