diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 55674307cf3d..697ea1fba91a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -98,6 +98,7 @@ import org.jetbrains.jps.api.JpsRemoteProto; import org.jetbrains.jps.api.JpsServerResponseHandler; import org.jetbrains.jps.api.RequestFuture; +import javax.swing.*; import java.io.*; import java.util.*; import java.util.concurrent.TimeUnit; @@ -415,8 +416,8 @@ public class CompileDriver { } @Nullable - private RequestFuture compileOnServer(final @NotNull CompileContextImpl compileContext, @NotNull Collection modules, @NotNull Collection artifacts, - final @NotNull Collection paths, @Nullable final CompileStatusNotification callback) + private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, @NotNull Collection modules, @NotNull Collection artifacts, + final @NotNull Collection paths, @Nullable final CompileStatusNotification callback) throws Exception { Collection moduleNames = Collections.emptyList(); if (modules.size() > 0) { @@ -546,10 +547,7 @@ public class CompileDriver { return buildManager.scheduleBuild(myProject, compileContext.isRebuild(), compileContext.isMake(), moduleNames, artifactNames, paths, builderParams, new DefaultMessageHandler(myProject) { @Override public void sessionTerminated() { - final ExitStatus status = COMPILE_SERVER_BUILD_STATUS.get(compileContext); - if (status != null) { - notifyCompilationCompleted(compileContext, callback, status); - } + notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext)); } @Override @@ -643,7 +641,7 @@ public class CompileDriver { final boolean checkCachesVersion) { ApplicationManager.getApplication().assertIsDispatchThread(); - final boolean useServer = useOutOfProcessBuild(); + final boolean useExtProcessBuild = useOutOfProcessBuild(); final String contentName = forceCompile ? CompilerBundle.message("compiler.content.name.compile") : CompilerBundle.message("compiler.content.name.make"); @@ -656,12 +654,12 @@ public class CompileDriver { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); FileDocumentManager.getInstance().saveAllDocuments(); - final DependencyCache dependencyCache = useServer? null: createDependencyCache(); + final DependencyCache dependencyCache = useExtProcessBuild ? null: createDependencyCache(); final CompileContextImpl compileContext = new CompileContextImpl(myProject, compileTask, scope, dependencyCache, !isRebuild && !forceCompile, isRebuild); compileContext.putUserData(COMPILATION_START_TIMESTAMP, LocalTimeCounter.currentTime()); - if (!useServer) { + if (!useExtProcessBuild) { for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) { final Pair outputs = entry.getValue(); final Pair key = entry.getKey(); @@ -673,21 +671,18 @@ public class CompileDriver { } final Runnable compileWork; - if (useServer) { + if (useExtProcessBuild) { compileWork = new Runnable() { public void run() { final ProgressIndicator indicator = compileContext.getProgressIndicator(); - if (indicator.isCanceled()) { + if (indicator.isCanceled() || myProject.isDisposed()) { if (callback != null) { callback.finished(true, 0, 0, compileContext); } return; } - long start = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); try { - if (myProject.isDisposed()) { - return; - } LOG.info("COMPILATION STARTED " + (CompilerWorkspaceConfiguration.useServerlessOutOfProcessBuild() ? "(BUILD PROCESS)" : "(COMPILE SERVER)")); if (message != null) { compileContext.addMessage(message); @@ -695,7 +690,7 @@ public class CompileDriver { final Collection paths = fetchFiles(compileContext); final List modules = paths.isEmpty()? Arrays.asList(compileContext.getCompileScope().getAffectedModules()) : Collections.emptyList(); final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(myProject, compileContext.getCompileScope(), true); - final RequestFuture future = compileOnServer(compileContext, modules, artifacts, paths, callback); + final RequestFuture future = compileInExternalProcess(compileContext, modules, artifacts, paths, callback); if (future != null) { while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -707,7 +702,7 @@ public class CompileDriver { callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext); } } - catch (Exception e) { + catch (Throwable e) { LOG.error(e); // todo callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext); } @@ -876,31 +871,35 @@ public class CompileDriver { } } + /** @noinspection SSBasedInspection*/ private void notifyCompilationCompleted(final CompileContextImpl compileContext, final CompileStatusNotification callback, final ExitStatus _status) { final long duration = System.currentTimeMillis() - compileContext.getStartCompilationStamp(); - ApplicationManager.getApplication().invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { public void run() { - if (myProject.isDisposed()) { - return; + int errorCount = 0; + int warningCount = 0; + try { + errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); + warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING); + if (!myProject.isDisposed()) { + final String statusMessage = createStatusMessage(_status, warningCount, errorCount); + final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO; + if (duration > ONE_MINUTE_MS) { + ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage); + } + CompilerManager.NOTIFICATION_GROUP.createNotification(_status == ExitStatus.UP_TO_DATE ? "Compilation: all files are up to date" : statusMessage, messageType).notify(myProject); + if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { + compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); + } + } } - final int errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); - final int warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING); - final String statusMessage = createStatusMessage(_status, warningCount, errorCount); - final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO; - if (duration > ONE_MINUTE_MS) { - ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage); - } - - CompilerManager.NOTIFICATION_GROUP.createNotification(_status == ExitStatus.UP_TO_DATE ? "Compilation: all files are up to date" : statusMessage, messageType).notify(myProject); - - if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { - compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); - } - if (callback != null) { - callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext); + finally { + if (callback != null) { + callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext); + } } } - }, ModalityState.NON_MODAL); + }); } private void checkCachesVersion(final CompileContextImpl compileContext, final long currentVFSTimestamp) { @@ -2316,10 +2315,10 @@ public class CompileDriver { } private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) { - if (useOutOfProcessBuild()) { - return true; - } try { + if (useOutOfProcessBuild()) { + return true; + } final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/; final List modulesWithoutOutputPathSpecified = new ArrayList(); boolean isProjectCompilePathSpecified = true; diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index cf1261f8440c..2f92bc5b9256 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -102,21 +102,6 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable { myProject = JavaDebuggerSupport.getCurrentProject(); } final JPanel panel = new JPanel(new GridBagLayout()); - myClassNameField = new TextFieldWithBrowseButton(new ActionListener() { - public void actionPerformed(ActionEvent e) { - PsiClass psiClass = DebuggerUtils.getInstance() - .chooseClassDialog(DebuggerBundle.message("title.compound.renderer.configurable.choose.renderer.reference.type"), myProject); - if (psiClass != null) { - myClassNameField.setText(JVMNameUtil.getNonAnonymousClassName(psiClass)); - } - } - }); - myClassNameField.getTextField().addFocusListener(new FocusAdapter() { - public void focusLost(FocusEvent e) { - final String qName = myClassNameField.getText(); - updateContext(qName); - } - }); myRbDefaultLabel = new JRadioButton(DebuggerBundle.message("label.compound.renderer.configurable.use.default.renderer")); myRbExpressionLabel = new JRadioButton(DebuggerBundle.message("label.compound.renderer.configurable.use.expression")); @@ -146,6 +131,22 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable { myRbListChildrenRenderer.addItemListener(updateListener); myRbExpressionChildrenRenderer.addItemListener(updateListener); + myClassNameField = new TextFieldWithBrowseButton(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PsiClass psiClass = DebuggerUtils.getInstance() + .chooseClassDialog(DebuggerBundle.message("title.compound.renderer.configurable.choose.renderer.reference.type"), myProject); + if (psiClass != null) { + myClassNameField.setText(JVMNameUtil.getNonAnonymousClassName(psiClass)); + } + } + }); + myClassNameField.getTextField().addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + final String qName = myClassNameField.getText(); + updateContext(qName); + } + }); + panel.add(new JLabel(DebuggerBundle.message("label.compound.renderer.configurable.apply.to")), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java index e7891d8930de..b4b7d42c9cfe 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java @@ -23,8 +23,6 @@ import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunProfileWithCompileBeforeLaunchOption; import com.intellij.execution.remote.RemoteConfiguration; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompileStatusNotification; @@ -34,6 +32,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; import com.intellij.util.concurrency.Semaphore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -109,20 +108,21 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider result = new Ref(Boolean.FALSE); try { + + final Semaphore done = new Semaphore(); + done.down(); final CompileStatusNotification callback = new CompileStatusNotification() { public void finished(final boolean aborted, final int errors, final int warnings, CompileContext compileContext) { if (errors == 0 && !aborted) { - result[0] = true; + result.set(Boolean.TRUE); } - done.up(); } }; - ApplicationManager.getApplication().invokeAndWait(new Runnable() { + SwingUtilities.invokeAndWait(new Runnable() { public void run() { CompileScope scope; final CompilerManager compilerManager = CompilerManager.getInstance(myProject); @@ -147,20 +147,22 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider 0) { PsiMethod constructor = elementFactory.createConstructor(); - constructor = (PsiMethod) aClass.add(constructor); + constructor = (PsiMethod)aClass.add(constructor); TemplateBuilderImpl templateBuilder = new TemplateBuilderImpl(aClass); CreateFromUsageUtils.setupMethodParameters(constructor, templateBuilder, argList, getTargetSubstitutor(newExpression)); @@ -120,7 +120,8 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { }; if (ApplicationManager.getApplication().isUnitTestMode()) { runnable.run(); - } else { + } + else { ApplicationManager.getApplication().invokeLater(runnable); } } @@ -136,7 +137,7 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { PsiMethod supConstructor = null; PsiClass superClass = targetClass.getSuperClass(); if (superClass != null && !"java.lang.Object".equals(superClass.getQualifiedName()) && - !"java.lang.Enum".equals(superClass.getQualifiedName())) { + !"java.lang.Enum".equals(superClass.getQualifiedName())) { PsiMethod[] constructors = superClass.getConstructors(); boolean hasDefaultConstructor = false; @@ -145,7 +146,8 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { hasDefaultConstructor = true; supConstructor = null; break; - } else { + } + else { supConstructor = superConstructor; } } @@ -269,4 +271,9 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { public String getFamilyName() { return QuickFixBundle.message("create.class.from.new.family"); } + + @Override + protected boolean canBeTargetClass(PsiClass psiClass) { + return false; + } } diff --git a/java/java-tests/testData/inspection/redundantCast/IDEADEV25675/src/A.java b/java/java-tests/testData/inspection/redundantCast/IDEADEV25675/src/A.java index cbead21aa913..074a0415074b 100644 --- a/java/java-tests/testData/inspection/redundantCast/IDEADEV25675/src/A.java +++ b/java/java-tests/testData/inspection/redundantCast/IDEADEV25675/src/A.java @@ -6,4 +6,10 @@ public class Test { public void bar(String[] array) { ((Object[]) array)[0] = new Object(); } + + public Object obj; + public static void setObjValueInArray(Test t, Object val) { + t.obj = new Object[1]; + ((Object[])t.obj)[0] = val; + } } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java index dfb44721dd25..494bf78c3a27 100644 --- a/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java +++ b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java @@ -443,8 +443,8 @@ public class RedundantCastUtil { PsiTypeElement typeElement = typeCast.getCastType(); if (typeElement == null) return; - PsiType castTo = typeElement.getType(); - PsiType opType = typeCast.getOperand().getType(); + final PsiType castTo = typeElement.getType(); + final PsiType opType = typeCast.getOperand().getType(); if (opType == null) return; if (parent instanceof PsiReferenceExpression) { if (castTo instanceof PsiClassType && opType instanceof PsiPrimitiveType) return; //explicit boxing @@ -460,8 +460,8 @@ public class RedundantCastUtil { } } - if (someWhereAtTheLeftSideOfAssignment(parent)) { - if (TypeConversionUtil.isAssignable(opType, castTo, false)) { + if (arrayAccessAtTheLeftSideOfAssignment(parent)) { + if (TypeConversionUtil.isAssignable(opType, castTo, false) && opType.getArrayDimensions() == castTo.getArrayDimensions()) { addToResults(typeCast); } } @@ -472,7 +472,7 @@ public class RedundantCastUtil { } } - private static boolean someWhereAtTheLeftSideOfAssignment(PsiElement element) { + private static boolean arrayAccessAtTheLeftSideOfAssignment(PsiElement element) { PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(element, PsiAssignmentExpression.class, false, PsiMember.class); if (assignment == null) return false; PsiExpression lExpression = assignment.getLExpression(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index 34722063c219..0b150efa781f 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -46,6 +46,7 @@ import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.search.PsiFileSystemItemProcessor; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; @@ -395,6 +396,10 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu if (parent.getFileSystem() == vFile.getFileSystem()) { copyVFile = vFile.copy(this, parent, newName); } + else if (vFile instanceof LightVirtualFile) { + copyVFile = parent.createChildData(this, newName); + copyVFile.setBinaryContent(originalFile.getText().getBytes(copyVFile.getCharset())); + } else { copyVFile = VfsUtilCore.copyFile(this, vFile, parent, newName); } diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java index 60cc1716b09b..d4b62b4a2b4a 100644 --- a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java +++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java @@ -238,7 +238,7 @@ class PrintManager { } private static TextPainter doInitTextPainter(@NotNull final DocumentEx doc, Project project) { - EditorHighlighter highlighter = HighlighterFactory.createHighlighter(project, FileTypes.PLAIN_TEXT); + EditorHighlighter highlighter = HighlighterFactory.createHighlighter(project, "unknown"); highlighter.setText(doc.getCharsSequence()); return new TextPainter(doc, highlighter, "unknown", project, FileTypes.PLAIN_TEXT, null); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java index 675a9e3d0ed8..e9e4b70ad820 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java @@ -188,4 +188,9 @@ public abstract class InspectionToolWrapper rootPaths = getAllRoots(false); - if (rootPaths == null) return; - myRootsToWatch = LocalFileSystem.getInstance().replaceWatchedRoots(myRootsToWatch, rootPaths, null); + final Pair, Set> roots = getAllRoots(false); + if (roots == null) return; + myRootsToWatch = LocalFileSystem.getInstance().replaceWatchedRoots(myRootsToWatch, roots.first, roots.second); } private void beforeRootsChange(boolean fileTypes) { @@ -165,11 +170,12 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { } private boolean affectsRoots(VirtualFilePointer[] pointers) { - Set roots = getAllRoots(true); + Pair, Set> roots = getAllRoots(true); if (roots == null) return false; for (VirtualFilePointer pointer : pointers) { - if (roots.contains(url2path(pointer.getUrl()))) return true; + final String path = url2path(pointer.getUrl()); + if (roots.first.contains(path) || roots.second.contains(path)) return true; } return false; @@ -208,61 +214,63 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { } @Nullable - private Set getAllRoots(boolean includeSourceRoots) { + private Pair, Set> getAllRoots(boolean includeSourceRoots) { if (myProject.isDefault()) return null; - final Set rootPaths = new HashSet(); - Module[] modules = ModuleManager.getInstance(myProject).getModules(); - for (Module module : modules) { - final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final String[] contentRootUrls = moduleRootManager.getContentRootUrls(); - rootPaths.addAll(getRootsToTrack(contentRootUrls)); - if (includeSourceRoots) { - final String[] sourceRootUrls = moduleRootManager.getSourceRootUrls(); - rootPaths.addAll(getRootsToTrack(sourceRootUrls)); + final Set recursive = new HashSet(); + final Set flat = new HashSet(); + + final String projectFilePath = myProject.getProjectFilePath(); + final File projectDirFile = new File(projectFilePath).getParentFile(); + if (projectDirFile != null && projectDirFile.getName().equals(Project.DIRECTORY_STORE_FOLDER)) { + recursive.add(projectDirFile.getAbsolutePath()); + } + else { + flat.add(projectFilePath); + final VirtualFile workspaceFile = myProject.getWorkspaceFile(); + if (workspaceFile != null) { + flat.add(workspaceFile.getPath()); } - rootPaths.add(module.getModuleFilePath()); } for (WatchedRootsProvider extension : Extensions.getExtensions(WatchedRootsProvider.EP_NAME, myProject)) { - rootPaths.addAll(extension.getRootsToWatch()); + recursive.addAll(extension.getRootsToWatch()); } - final String projectFile = myProject.getProjectFilePath(); - rootPaths.add(projectFile); - final VirtualFile baseDir = myProject.getBaseDir(); - if (baseDir != null) { - rootPaths.add(baseDir.getPath()); - } - // No need to add workspace file separately since they're definitely on same directory with ipr. - + final Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module module : modules) { final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + + addRootsToTrack(moduleRootManager.getContentRootUrls(), recursive, flat); + if (includeSourceRoots) { + addRootsToTrack(moduleRootManager.getSourceRootUrls(), recursive, flat); + } + flat.add(module.getModuleFilePath()); + final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); for (OrderEntry entry : orderEntries) { if (entry instanceof LibraryOrderEntry) { final Library library = ((LibraryOrderEntry)entry).getLibrary(); - for (OrderRootType orderRootType : OrderRootType.getAllTypes()) { - rootPaths.addAll(getRootsToTrack(library, orderRootType)); + if (library != null) { + for (OrderRootType orderRootType : OrderRootType.getAllTypes()) { + addRootsToTrack(library.getUrls(orderRootType), recursive, flat); + } } } else if (entry instanceof JdkOrderEntry) { for (OrderRootType orderRootType : OrderRootType.getAllTypes()) { - rootPaths.addAll(getRootsToTrack(entry, orderRootType)); + addRootsToTrack(entry.getUrls(orderRootType), recursive, flat); } } } - } - for (Module module : modules) { - final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final String explodedDirectory = moduleRootManager.getExplodedDirectoryUrl(); if (explodedDirectory != null) { - rootPaths.add(extractLocalPath(explodedDirectory)); + recursive.add(extractLocalPath(explodedDirectory)); } } - return rootPaths; + return Pair.create(recursive, flat); } @Override @@ -271,26 +279,18 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { DumbServiceImpl.getInstance(myProject).queueCacheUpdate(myRootsChangeUpdaters); } - private static Collection getRootsToTrack(final Library library, final OrderRootType rootType) { - return library != null ? getRootsToTrack(library.getUrls(rootType)) : Collections.emptyList(); - } - - private static Collection getRootsToTrack(final OrderEntry library, final OrderRootType rootType) { - return library != null ? getRootsToTrack(library.getUrls(rootType)) : Collections.emptyList(); - } - - private static List getRootsToTrack(final String[] urls) { - final List result = new ArrayList(urls.length); + private static void addRootsToTrack(final String[] urls, final Collection recursive, final Collection flat) { for (String url : urls) { if (url != null) { final String protocol = VirtualFileManager.extractProtocol(url); - if (protocol == null || JarFileSystem.PROTOCOL.equals(protocol) || LocalFileSystem.PROTOCOL.equals(protocol)) { - result.add(extractLocalPath(url)); + if (protocol == null || LocalFileSystem.PROTOCOL.equals(protocol)) { + recursive.add(extractLocalPath(url)); + } + else if (JarFileSystem.PROTOCOL.equals(protocol)) { + flat.add(extractLocalPath(url)); } } } - - return result; } @Override @@ -356,5 +356,4 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { } } } - } diff --git a/platform/platform-api/src/com/intellij/openapi/application/BaseActionRunnable.java b/platform/platform-api/src/com/intellij/openapi/application/BaseActionRunnable.java index 90164248e2d1..7479341ed78f 100644 --- a/platform/platform-api/src/com/intellij/openapi/application/BaseActionRunnable.java +++ b/platform/platform-api/src/com/intellij/openapi/application/BaseActionRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ public abstract class BaseActionRunnable { return ApplicationManager.getApplication(); } - /** Same as execute() but do not log error if exception occured. */ + /** Same as execute() but do not log error if exception occurred. */ public final RunResult executeSilently() { mySilentExecution = true; return execute(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java index cfc597611856..b8b031ba44a7 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java @@ -228,7 +228,12 @@ public abstract class DialogWrapper { } //validation - private final Alarm myValidationAlarm = new Alarm(myDisposable); + private final Alarm myValidationAlarm = new Alarm(getValidationThreadToUse(), myDisposable); + + protected Alarm.ThreadToUse getValidationThreadToUse() { + return Alarm.ThreadToUse.SWING_THREAD; + } + private int myValidationDelay = 300; private boolean myDisposed = false; private boolean myValidationStarted = false; @@ -281,7 +286,12 @@ public abstract class DialogWrapper { private void installErrorPainter() { if (myErrorPainterInstalled) return; myErrorPainterInstalled = true; - IdeGlassPaneUtil.installPainter(myErrorPane, myErrorPainter, myDisposable); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + IdeGlassPaneUtil.installPainter(myErrorPane, myErrorPainter, myDisposable); + } + }); } private void clearProblems() { @@ -1150,8 +1160,9 @@ public abstract class DialogWrapper { protected final void initValidation() { myValidationAlarm.cancelAllRequests(); - myValidationAlarm.addRequest(new Runnable() { + final Runnable validateRequest = new Runnable() { public void run() { + if (myDisposed) return; final ValidationInfo result = doValidate(); if (result == null) { clearProblems(); @@ -1164,7 +1175,13 @@ public abstract class DialogWrapper { initValidation(); } } - }, myValidationDelay, ModalityState.current()); + }; + + if (getValidationThreadToUse() == Alarm.ThreadToUse.SWING_THREAD) { + myValidationAlarm.addRequest(validateRequest, myValidationDelay, ModalityState.current()); + } else { + myValidationAlarm.addRequest(validateRequest, myValidationDelay); + } } protected boolean isNorthStrictedToPreferredSize() { diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java index 4e3767db2567..06e05fc8e15d 100644 --- a/platform/platform-api/src/com/intellij/ui/table/TableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java @@ -91,6 +91,7 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel final List current = sorter == null ? null : sorter.getSortKeys(); ColumnInfo[] columns = getListTableModel().getColumnInfos(); int[] sizeMode = new int[columns.length]; + int[] headers = new int[columns.length]; int[] widths = new int[columns.length]; int fixedWidth = 0; int varWidth = 0; @@ -111,26 +112,24 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel if (sorter != null && columnInfo.isSortable()) { sorter.setSortKeys(current); } - final Dimension headerSize = headerComponent == null? new Dimension(0, 0) : headerComponent.getPreferredSize(); + if (headerComponent != null) { + headers[i] = headerComponent.getPreferredSize().width; + } final String maxStringValue; final String preferredValue; if (columnInfo.getWidth(this) > 0) { - sizeMode[i] = 0; + sizeMode[i] = 1; int width = columnInfo.getWidth(this); widths[i] = width; } - else if ((maxStringValue = columnInfo.getMaxStringValue(this)) != null) { - sizeMode[i] = 1; - int width = getFontMetrics(getFont()).stringWidth(maxStringValue) + columnInfo.getAdditionalWidth(); - width = Math.max(width, headerSize.width); - widths[i] = width; + else if ((maxStringValue = columnInfo.getMaxStringValue()) != null) { + sizeMode[i] = 2; + widths[i] = getFontMetrics(getFont()).stringWidth(maxStringValue) + columnInfo.getAdditionalWidth(); varCount ++; } else if ((preferredValue = columnInfo.getPreferredStringValue()) != null) { - sizeMode[i] = 2; - int width = getFontMetrics(getFont()).stringWidth(preferredValue) + columnInfo.getAdditionalWidth(); - width = Math.max(width, headerSize.width); - widths[i] = width; + sizeMode[i] = 3; + widths[i] = getFontMetrics(getFont()).stringWidth(preferredValue) + columnInfo.getAdditionalWidth(); varCount ++; } if (sizeMode[i] == 0) { @@ -141,25 +140,25 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel } } - // apply + // apply: distribute available space between resizable columns but no more than *4 times. + // and make sure that header will fit as well int viewWidth = getParent() != null? getParent().getWidth() : getWidth(); int addendum = varCount > 0 && viewWidth > fixedWidth + varWidth? (viewWidth - fixedWidth - varWidth) / varCount : 0; for (int i=0 ; i myLastComponent; public Image getVolatileOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) { + if (proposedWidth <= 0 || proposedHeight <= 0) return null; final Image buffer = super.getVolatileOffscreenBuffer(c, proposedWidth, proposedHeight); clearLeakyImages(false); // DisplayChangedListener might be unavailable return buffer; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java index fed864a1432f..0d65d499a8dd 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java @@ -41,7 +41,7 @@ import java.io.IOException; import java.util.*; public class FileWatcherTest extends PlatformLangTestCase { - private static final int NATIVE_PROCESS_DELAY = 500; // time to event to be caught by native watcher and passed to watcher thread + private static final int NATIVE_PROCESS_DELAY = 750; // time to event to be caught by native watcher and passed to watcher thread private FileWatcher myWatcher; private LocalFileSystem myFileSystem; @@ -123,7 +123,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileCreateEvent.class, file.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); delete(file); } } @@ -150,7 +150,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileCreateEvent.class, file.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); delete(file); } } @@ -178,7 +178,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileCreateEvent.class, file.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); delete(topDir); } } @@ -199,7 +199,31 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileEvent.class); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); + delete(topDir); + } + } + + public void testDirectoryMixed() throws Exception { + final File topDir = FileUtil.createTempDirectory("top.", null); + final File watchedFile1 = FileUtil.createTempFile(topDir, "test.", ".txt", true, false); + final File sub1Dir = FileUtil.createTempDirectory(topDir, "sub1.", null); + final File unwatchedFile = FileUtil.createTempFile(sub1Dir, "test.", ".txt", true, false); + final File sub2Dir = FileUtil.createTempDirectory(topDir, "sub2.", null); + final File sub2subDir = FileUtil.createTempDirectory(sub2Dir, "sub2.", null); + final File watchedFile2 = FileUtil.createTempFile(sub2subDir, "test.", ".txt", true, false); + refresh(topDir); + + final LocalFileSystem.WatchRequest topRequest = watch(topDir, false); + final LocalFileSystem.WatchRequest subRequest = watch(sub2Dir); + try { + FileUtil.writeToFile(watchedFile1, "new content"); + FileUtil.writeToFile(watchedFile2, "new content"); + FileUtil.writeToFile(unwatchedFile, "new content"); + assertEvent(VFileContentChangeEvent.class, watchedFile1.getAbsolutePath(), watchedFile2.getAbsolutePath()); + } + finally { + unwatch(subRequest, topRequest); delete(topDir); } } @@ -220,7 +244,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileCreateEvent.class, file.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); delete(topDir); } } @@ -265,7 +289,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileDeleteEvent.class, file1.getAbsolutePath(), file2.getAbsolutePath(), file3.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoots(Arrays.asList(request1, request2)); + unwatch(request1, request2); delete(topDir); } } @@ -381,7 +405,7 @@ public class FileWatcherTest extends PlatformLangTestCase { assertEvent(VFileCreateEvent.class, substFile.getAbsolutePath()); } finally { - myFileSystem.removeWatchedRoot(request); + unwatch(request); } } finally { @@ -429,8 +453,8 @@ public class FileWatcherTest extends PlatformLangTestCase { return request; } - private void unwatch(final LocalFileSystem.WatchRequest request) throws InterruptedException { - myFileSystem.removeWatchedRoot(request); + private void unwatch(final LocalFileSystem.WatchRequest... requests) throws InterruptedException { + myFileSystem.removeWatchedRoots(Arrays.asList(requests)); waitForResponse(); clearEvents(); } @@ -451,7 +475,7 @@ public class FileWatcherTest extends PlatformLangTestCase { private void delete(@NotNull final File file) throws IOException { final VirtualFile vFile = myFileSystem.findFileByIoFile(file); if (vFile != null) { - final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass()); + @SuppressWarnings("deprecation") final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass()); try { vFile.delete(this); } diff --git a/platform/util/src/com/intellij/util/ui/ColumnInfo.java b/platform/util/src/com/intellij/util/ui/ColumnInfo.java index 579fdd644609..98add315824d 100644 --- a/platform/util/src/com/intellij/util/ui/ColumnInfo.java +++ b/platform/util/src/com/intellij/util/ui/ColumnInfo.java @@ -93,7 +93,7 @@ public abstract class ColumnInfo { } @Nullable - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return null; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java index c01f87d1bb8a..3bbaed4fbef4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java @@ -55,10 +55,7 @@ import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.*; import com.intellij.ui.content.ContentManager; -import com.intellij.ui.dualView.CellWrapper; -import com.intellij.ui.dualView.DualTreeElement; -import com.intellij.ui.dualView.DualView; -import com.intellij.ui.dualView.DualViewColumnInfo; +import com.intellij.ui.dualView.*; import com.intellij.ui.table.TableView; import com.intellij.util.*; import com.intellij.util.text.DateFormatUtil; @@ -152,12 +149,12 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } @Override - public String getMaxStringValue(JTable table) { - return getMaxValue(getName(), table); + public String getMaxStringValue() { + return getMaxValue(getName()); } }; - private static final DualViewColumnInfo DATE = new VcsColumnInfo(VcsBundle.message("column.name.revision.date")) { + private final DualViewColumnInfo DATE = new VcsColumnInfo(VcsBundle.message("column.name.revision.date")) { protected String getDataOf(VcsFileRevision object) { Date date = object.getRevisionDate(); if (date == null) return ""; @@ -174,8 +171,8 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } @Override - public String getMaxStringValue(JTable table) { - return getMaxValue(getName(), table); + public String getMaxStringValue() { + return getMaxValue(getName()); } }; private final Splitter myDetailsSplitter = new Splitter(false, 0.5f); @@ -216,7 +213,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { private static final TableCellRenderer AUTHOR_RENDERER = new AuthorCellRenderer(); - private static final DualViewColumnInfo AUTHOR = new VcsColumnInfo(VcsBundle.message("column.name.revision.list.author")) { + private final DualViewColumnInfo AUTHOR = new VcsColumnInfo(VcsBundle.message("column.name.revision.list.author")) { protected String getDataOf(VcsFileRevision object) { VcsFileRevision rev = object; if (object instanceof TreeNodeOnVcsRevision) { @@ -265,8 +262,8 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } @Override - public String getMaxStringValue(JTable table) { - return getMaxValue(getName(), table); + public String getMaxStringValue() { + return getMaxValue(getName()); } }; @@ -292,7 +289,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } - private static class MessageColumnInfo extends VcsColumnInfo { + private class MessageColumnInfo extends VcsColumnInfo { private final MessageRenderer myRenderer; public MessageColumnInfo(Project project) { @@ -319,18 +316,6 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } } - private static int getSuitableIndex(int index10, int index13) { - if (index10 < 0) { - return index13; - } - else if (index13 < 0) { - return index10; - } - else { - return Math.min(index10, index13); - } - } - @Override public String getPreferredStringValue() { return StringUtil.repeatSymbol('a', 125); @@ -341,11 +326,24 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } @Override - public String getMaxStringValue(JTable table) { - return getMaxValue(getName(), table); + public String getMaxStringValue() { + return getMaxValue(getName()); } } + private static int getSuitableIndex(int index10, int index13) { + if (index10 < 0) { + return index13; + } + else if (index13 < 0) { + return index10; + } + else { + return Math.min(index10, index13); + } + } + + private final Map myRevisionToVirtualFile = new HashMap(); public FileHistoryPanelImpl(AbstractVcs vcs, @@ -519,7 +517,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { return columns.toArray(new DualViewColumnInfo[columns.size()]); } - private static Collection wrapAdditionalColumns(ColumnInfo[] additionalColumns) { + private Collection wrapAdditionalColumns(ColumnInfo[] additionalColumns) { ArrayList result = new ArrayList(); if (additionalColumns != null) { for (ColumnInfo additionalColumn : additionalColumns) { @@ -1504,7 +1502,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { } - private static class MyColumnWrapper extends DualViewColumnInfo { + private class MyColumnWrapper extends DualViewColumnInfo { private final ColumnInfo myBaseColumn; public Comparator getComparator() { @@ -1548,10 +1546,10 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { return myBaseColumn.getEditor(item.myRevision); } - public String getMaxStringValue(JTable table) { - final String superValue = myBaseColumn.getMaxStringValue(table); + public String getMaxStringValue() { + final String superValue = myBaseColumn.getMaxStringValue(); if (superValue != null) return superValue; - return getMaxValue(myBaseColumn.getName(), table); + return getMaxValue(myBaseColumn.getName()); } public int getAdditionalWidth() { @@ -1592,7 +1590,9 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { return myFilePath.getVirtualFileParent(); } - private static String getMaxValue(String name, JTable table) { + private String getMaxValue(String name) { + if (myDualView == null) return null; + TableView table = myDualView.getFlatView(); if (table.getRowCount() == 0) return null; final Enumeration columns = table.getColumnModel().getColumns(); int idx = 0; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java index 4959cf997cf3..1fe8cf89fe14 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.java @@ -100,7 +100,7 @@ public class MultipleFileMergeDialog extends DialogWrapper { } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return VcsBundle.message("multiple.file.merge.type.binary"); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java index 6d36f90020b5..953db64cab8b 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java @@ -45,8 +45,15 @@ public class RadFragment extends RadViewComponent implements IConfigurableCompon setValue(fragment); } } - }); - private static final Property TAG_PROPERTY = new FragmentProperty("tag", new TextEditor()); + }, "Supply the name of the fragment class to instantiate."); + private static final Property TAG_PROPERTY = new FragmentProperty("tag", new TextEditor(), + "Use device-admin as the root tag of the XML resource that\n" + + "describes a\n" + + " {@link android.app.admin.DeviceAdminReceiver}, which is\n" + + " referenced from its\n" + + " {@link android.app.admin.DeviceAdminReceiver#DEVICE_ADMIN_META_DATA}\n" + + " meta-data entry. Described here are the attributes that can be\n" + + " included in that tag."); private static final String NAME_KEY = "fragment.name"; @Override diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java index 793360bc8b08..a087b5511066 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java @@ -113,4 +113,9 @@ public class CenterProperty extends Property { public PropertyEditor getEditor() { return myEditor; } + + @Override + public String getJavadocText() { + return "Set centers this child horizontally or vertically within its parent."; + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CompoundProperty.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CompoundProperty.java index 2b1b4451a848..d25594f28df7 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CompoundProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CompoundProperty.java @@ -23,8 +23,11 @@ import org.jetbrains.annotations.NotNull; * @author Alexander Lobas */ public class CompoundProperty extends com.intellij.android.designer.propertyTable.CompoundProperty { - public CompoundProperty(@NotNull String name) { + private final String myJavadocText; + + public CompoundProperty(@NotNull String name, String javadocText) { super(name); + myJavadocText = javadocText; setImportant(true); } @@ -42,4 +45,9 @@ public class CompoundProperty extends com.intellij.android.designer.propertyTabl } return value.append("]").toString(); } + + @Override + public String getJavadocText() { + return myJavadocText; + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java index c2d573943077..555ee8f16ad4 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java @@ -53,7 +53,8 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD @Override public void configureProperties(List properties) { - CompoundProperty alignComponent = new CompoundProperty("layout:alignComponent"); + CompoundProperty alignComponent = + new CompoundProperty("layout:alignComponent", "Positions the edges of this view to the edges of the another view."); PropertyParser.moveProperties(properties, alignComponent, "layout:alignTop", "top:top", "layout:below", "top:bottom", @@ -66,7 +67,8 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD "layout:alignBaseline", "baseline:baseline"); properties.add(alignComponent); - CompoundProperty alignParent = new CompoundProperty("layout:alignParent"); + CompoundProperty alignParent = + new CompoundProperty("layout:alignParent", "Positions the edges of this view to the edges of the parent."); PropertyParser.moveProperties(properties, alignParent, "layout:alignParentTop", "top", "layout:alignParentLeft", "left", diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java index cf2def4a359c..f768db303a3c 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java @@ -134,4 +134,9 @@ public class AttributeProperty extends Property { public PropertyEditor getEditor() { return myEditor; } + + @Override + public String getJavadocText() { + return myDefinition.getDocValue(); + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CompoundProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CompoundProperty.java index caba3f1987e2..de53935684fe 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CompoundProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CompoundProperty.java @@ -121,4 +121,9 @@ public class CompoundProperty extends Property implements IPro public PropertyEditor getEditor() { return null; } + + @Override + public String getJavadocText() { + return myChildren.isEmpty() ? null : myChildren.get(0).getJavadocText(); + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java index 954de1ccbfa1..8d02639ad0b0 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java @@ -119,4 +119,9 @@ public class CustomViewProperty extends Property { public PropertyEditor getEditor() { return myEditor; } + + @Override + public String getJavadocText() { + return "The fully qualified name of the class."; + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java index 2bb6d28ea3b3..200478958a73 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java @@ -161,6 +161,11 @@ public class FlagProperty extends Property implements IPropert }); } + @Override + public String getJavadocText() { + return myDefinition.getDocValue(); + } + ////////////////////////////////////////////////////////////////////////////////////////// // // Option diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FragmentProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FragmentProperty.java index 908ddfe5dd0d..037eb07c9340 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FragmentProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FragmentProperty.java @@ -36,10 +36,12 @@ public class FragmentProperty extends Property { private final String myAttribute; private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); private final PropertyEditor myEditor; + private final String myJavadocText; - public FragmentProperty(@NotNull String name, PropertyEditor editor) { + public FragmentProperty(@NotNull String name, PropertyEditor editor, String javadocText) { super(null, name); myEditor = editor; + myJavadocText = javadocText; setImportant(true); myAttribute = "android:" + name; } @@ -97,4 +99,9 @@ public class FragmentProperty extends Property { public PropertyEditor getEditor() { return myEditor; } + + @Override + public String getJavadocText() { + return myJavadocText; + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java index 68fa3fa42e4e..1835911adbfb 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java @@ -88,4 +88,9 @@ public class IncludeLayoutProperty extends Property { public PropertyEditor getEditor() { return myEditor; } + + @Override + public String getJavadocText() { + return "Reference to the layout file you wish to include."; + } } \ No newline at end of file diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyProcessor.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyProcessor.java new file mode 100644 index 000000000000..69588f03c2fc --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyProcessor.java @@ -0,0 +1,24 @@ +package org.jetbrains.jps.android; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * @author Eugene.Kudelevsky + */ +public abstract class AndroidDependencyProcessor { + public void processExternalLibrary(@NotNull File file) { + } + + public void processAndroidLibraryPackage(@NotNull File file) { + } + + public void processAndroidLibraryOutputDirectory(@NotNull File dir) { + } + + public void processJavaModuleOutputDirectory(@NotNull File dir) { + } + + public abstract boolean isToProcess(@NotNull AndroidDependencyType type); +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyType.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyType.java new file mode 100644 index 000000000000..177c489635b4 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDependencyType.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.android; + +/** + * @author Eugene.Kudelevsky + */ +public enum AndroidDependencyType { + EXTERNAL_LIBRARY, ANDROID_LIBRARY_PACKAGE, JAVA_MODULE_OUTPUT_DIR, ANDROID_LIBRARY_OUTPUT_DIRECTORY +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java index 1c9698795948..d0dc6b7ddd36 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java @@ -17,6 +17,8 @@ package org.jetbrains.jps.android; import com.android.sdklib.IAndroidTarget; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.ArrayUtil; @@ -29,10 +31,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.Module; import org.jetbrains.jps.ProjectPaths; -import org.jetbrains.jps.incremental.CompileContext; -import org.jetbrains.jps.incremental.ExternalProcessUtil; -import org.jetbrains.jps.incremental.ProjectBuildException; -import org.jetbrains.jps.incremental.ProjectLevelBuilder; +import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.incremental.messages.ProgressMessage; @@ -50,6 +49,9 @@ public class AndroidDexBuilder extends ProjectLevelBuilder { @NonNls private static final String BUILDER_NAME = "android-dex"; + private static final Key BUILD_LISTENER_KEY = Key.create("BUILD_LISTENER_KEY"); + public static final Key> DIRTY_OUTPUT_DIRS = Key.create("DIRTY_OUTPUT_DIRS"); + @Override public void build(CompileContext context) throws ProjectBuildException { if (!AndroidJpsUtil.containsAndroidFacet(context.getProject()) || AndroidJpsUtil.isLightBuild(context)) { @@ -146,6 +148,8 @@ public class AndroidDexBuilder extends ProjectLevelBuilder { } final Set fileSet; + final Set jars; + final Set outputDirs; try { if (proguardCfgPath != null) { @@ -157,33 +161,73 @@ public class AndroidDexBuilder extends ProjectLevelBuilder { success = false; continue; } - fileSet = Collections.singleton(outputJarPath); + fileSet = jars = Collections.singleton(outputJarPath); + outputDirs = Collections.emptySet(); } else { fileSet = new HashSet(); - AndroidJpsUtil.addSubdirectories(classesDir, fileSet); - fileSet.addAll(externalLibraries); + jars = new HashSet(); + outputDirs = new HashSet(); - for (String filePath : AndroidJpsUtil.getClassdirsOfDependentModulesAndPackagesLibraries(projectPaths, module)) { - if (!classesDir.getPath().equals(filePath)) { - fileSet.add(filePath); + AndroidJpsUtil.addSubdirectories(classesDir, fileSet); + outputDirs.add(classesDir.getPath()); + + fileSet.addAll(externalLibraries); + jars.addAll(externalLibraries); + + AndroidJpsUtil.processClasspath(projectPaths, module, new AndroidDependencyProcessor() { + @Override + public void processExternalLibrary(@NotNull File file) { + fileSet.add(file.getPath()); + jars.add(file.getPath()); } - } + + @Override + public void processAndroidLibraryPackage(@NotNull File file) { + fileSet.add(file.getPath()); + jars.add(file.getPath()); + } + + @Override + public void processJavaModuleOutputDirectory(@NotNull File dir) { + fileSet.add(dir.getPath()); + outputDirs.add(dir.getPath()); + } + + @Override + public boolean isToProcess(@NotNull AndroidDependencyType type) { + return type == AndroidDependencyType.JAVA_MODULE_OUTPUT_DIR || + type == AndroidDependencyType.ANDROID_LIBRARY_PACKAGE || + type == AndroidDependencyType.EXTERNAL_LIBRARY; + } + }); if (facet.isPackTestCode()) { final File testsClassDir = projectPaths.getModuleOutputDir(module, true); if (testsClassDir != null && testsClassDir.isDirectory()) { AndroidJpsUtil.addSubdirectories(testsClassDir, fileSet); + outputDirs.add(testsClassDir.getPath()); } } } - final AndroidFileSetState newState = new AndroidFileSetState(fileSet, AndroidJpsUtil.CLASSES_AND_JARS_FILTER, true); + final AndroidFileSetState newState = new AndroidFileSetState(jars, AndroidJpsUtil.CLASSES_AND_JARS_FILTER, true); if (context.isMake()) { final AndroidFileSetState oldState = dexStateStorage.getState(module.getName()); if (oldState != null && oldState.equalsTo(newState)) { - continue; + final Set dirtyOutputDirs = context.getUserData(DIRTY_OUTPUT_DIRS); + boolean outputDirsDirty = false; + + for (String outputDir : outputDirs) { + if (dirtyOutputDirs.contains(outputDir)) { + outputDirsDirty = true; + break; + } + } + if (!outputDirsDirty) { + continue; + } } } @@ -225,6 +269,29 @@ public class AndroidDexBuilder extends ProjectLevelBuilder { return "Android Dex Builder"; } + @Override + public void buildStarted(CompileContext context) { + final HashSet dirtyOutputDirs = new HashSet(); + final BuildListener listener = new BuildListener() { + @Override + public void filesGenerated(Collection> paths) { + for (Pair path : paths) { + dirtyOutputDirs.add(path.first); + } + } + }; + context.putUserData(DIRTY_OUTPUT_DIRS, dirtyOutputDirs); + context.putUserData(BUILD_LISTENER_KEY, listener); + context.addBuildListener(listener); + } + + @Override + public void buildFinished(CompileContext context) { + final BuildListener listener = context.getUserData(BUILD_LISTENER_KEY); + assert listener != null; + context.removeBuildListener(listener); + } + private static boolean runDex(@NotNull AndroidPlatform platform, @NotNull String outputDir, @NotNull String[] compileTargets, @@ -308,34 +375,54 @@ public class AndroidDexBuilder extends ProjectLevelBuilder { final ProjectPaths paths = context.getProjectPaths(); final Set classFilesDirs = new HashSet(); final Set libClassFilesDirs = new HashSet(); + final Set outputDirs = new HashSet(); AndroidJpsUtil.addSubdirectories(classesDir, classFilesDirs); + outputDirs.add(classesDir.getPath()); - for (String depPath : AndroidJpsUtil.getClassdirsOfDependentModulesAndPackagesLibraries(paths, module)) { - final File depFile = new File(depPath); - if (depFile.isDirectory()) { - AndroidJpsUtil.addSubdirectories(depFile, classFilesDirs); + AndroidJpsUtil.processClasspath(paths, module, new AndroidDependencyProcessor() { + + @Override + public void processAndroidLibraryOutputDirectory(@NotNull File dir) { + AndroidJpsUtil.addSubdirectories(dir, libClassFilesDirs); + outputDirs.add(dir.getPath()); } - else { - AndroidJpsUtil.addSubdirectories(depFile.getParentFile(), libClassFilesDirs); + + @Override + public void processJavaModuleOutputDirectory(@NotNull File dir) { + AndroidJpsUtil.addSubdirectories(dir, classFilesDirs); + outputDirs.add(dir.getPath()); } - } + + @Override + public boolean isToProcess(@NotNull AndroidDependencyType type) { + return type == AndroidDependencyType.ANDROID_LIBRARY_OUTPUT_DIRECTORY || + type == AndroidDependencyType.JAVA_MODULE_OUTPUT_DIR; + } + }); final String logsDirOsPath = FileUtil.toSystemDependentName(mainContentRoot.getPath() + '/' + AndroidCommonUtils.DIRECTORY_FOR_LOGS_NAME); + final AndroidFileSetState newState = new AndroidFileSetState(externalJars, AndroidJpsUtil.CLASSES_AND_JARS_FILTER, true); - final Set allFiles = new HashSet(); - allFiles.addAll(classFilesDirs); - allFiles.addAll(libClassFilesDirs); - allFiles.addAll(externalJars); + if (context.isMake()) { + final AndroidFileSetState oldState = proguardStateStorage.getState(module.getName()); + if (context.getTimestamps().getStamp(proguardCfgFile) == proguardCfgFile.lastModified() && + newState.equalsTo(oldState)) { - final AndroidFileSetState newState = new AndroidFileSetState(allFiles, AndroidJpsUtil.CLASSES_AND_JARS_FILTER, true); - final AndroidFileSetState oldState = proguardStateStorage.getState(module.getName()); - if (context.getTimestamps().getStamp(proguardCfgFile) == proguardCfgFile.lastModified() && - newState.equalsTo(oldState)) { - return true; + final Set dirtyOutputDirs = context.getUserData(DIRTY_OUTPUT_DIRS); + assert dirtyOutputDirs != null; + boolean outputDirsDirty = false; + for (String outputDir : outputDirs) { + if (dirtyOutputDirs.contains(outputDir)) { + outputDirsDirty = true; + } + } + if (!outputDirsDirty) { + return true; + } + } } - final String[] classFilesDirOsPaths = ArrayUtil.toStringArray(classFilesDirs); final String[] libClassFilesDirOsPaths = ArrayUtil.toStringArray(libClassFilesDirs); final String[] externalJarOsPaths = ArrayUtil.toStringArray(externalJars); diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java index c2eeff28008a..9115b748026a 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java @@ -164,7 +164,18 @@ class AndroidJpsUtil { @NotNull public static Set getExternalLibraries(@NotNull ProjectPaths paths, @NotNull Module module, @NotNull AndroidPlatform platform) { final Set result = new HashSet(); - fillClasspath(paths, module, null, result, new HashSet(), false); + final AndroidDependencyProcessor processor = new AndroidDependencyProcessor() { + @Override + public void processExternalLibrary(@NotNull File file) { + result.add(file.getPath()); + } + + @Override + public boolean isToProcess(@NotNull AndroidDependencyType type) { + return type == AndroidDependencyType.EXTERNAL_LIBRARY; + } + }; + processClasspath(paths, module, processor); addAnnotationsJarIfNecessary(platform, result); return result; } @@ -180,24 +191,20 @@ class AndroidJpsUtil { } } - @NotNull - public static Set getClassdirsOfDependentModulesAndPackagesLibraries(@NotNull ProjectPaths paths, @NotNull Module module) { - final Set result = new HashSet(); - fillClasspath(paths, module, result, null, new HashSet(), false); - return result; + public static void processClasspath(@NotNull ProjectPaths paths, @NotNull Module module, @NotNull AndroidDependencyProcessor processor) { + processClasspath(paths, module, processor, new HashSet(), false); } - private static void fillClasspath(@NotNull ProjectPaths paths, - @NotNull final Module module, - @Nullable final Set outputDirs, - @Nullable final Set libraries, - @NotNull final Set visitedModules, - final boolean exportedLibrariesOnly) { + private static void processClasspath(@NotNull ProjectPaths paths, + @NotNull final Module module, + @NotNull final AndroidDependencyProcessor processor, + @NotNull final Set visitedModules, + final boolean exportedLibrariesOnly) { if (!visitedModules.add(module.getName())) { return; } - if (libraries != null) { + if (processor.isToProcess(AndroidDependencyType.EXTERNAL_LIBRARY)) { for (ClasspathItem item : module.getClasspath(ClasspathKind.PRODUCTION_RUNTIME, exportedLibrariesOnly)) { if (item instanceof Library && !(item instanceof Sdk)) { for (Object filePathObj : ((Library)item).getClasspath()) { @@ -208,7 +215,7 @@ class AndroidJpsUtil { processClassFilesAndJarsRecursively(filePath, new Processor() { @Override public boolean process(File file) { - libraries.add(file.getPath()); + processor.processExternalLibrary(file); return true; } }); @@ -225,20 +232,25 @@ class AndroidJpsUtil { final boolean depLibrary = depFacet != null && depFacet.isLibrary(); final File depClassDir = paths.getModuleOutputDir(depModule, false); - if (outputDirs != null && depClassDir != null) { + if (depClassDir != null) { if (depLibrary) { - final File packagedClassesJar = new File(depClassDir, AndroidCommonUtils.CLASSES_JAR_FILE_NAME); + if (processor.isToProcess(AndroidDependencyType.ANDROID_LIBRARY_PACKAGE)) { + final File packagedClassesJar = new File(depClassDir, AndroidCommonUtils.CLASSES_JAR_FILE_NAME); - if (packagedClassesJar.isFile()) { - outputDirs.add(packagedClassesJar.getPath()); + if (packagedClassesJar.isFile()) { + processor.processAndroidLibraryPackage(packagedClassesJar); + } + } + if (processor.isToProcess(AndroidDependencyType.ANDROID_LIBRARY_OUTPUT_DIRECTORY)) { + processor.processAndroidLibraryOutputDirectory(depClassDir); } } - else if (depFacet == null && depClassDir.isDirectory()) { + else if (processor.isToProcess(AndroidDependencyType.JAVA_MODULE_OUTPUT_DIR) && depFacet == null && depClassDir.isDirectory()) { // do not support android-app->android-app compile dependencies - outputDirs.add(depClassDir.getPath()); + processor.processJavaModuleOutputDirectory(depClassDir); } } - fillClasspath(paths, depModule, outputDirs, libraries, visitedModules, !depLibrary || exportedLibrariesOnly); + processClasspath(paths, depModule, processor, visitedModules, !depLibrary || exportedLibrariesOnly); } } } diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidLibraryPackagingBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidLibraryPackagingBuilder.java index 827e177c5930..ce3943375a6f 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidLibraryPackagingBuilder.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidLibraryPackagingBuilder.java @@ -45,61 +45,53 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder { private static ModuleLevelBuilder.ExitCode doBuild(CompileContext context, ModuleChunk chunk) throws IOException { boolean success = true; - final AndroidFileSetStorage storage = new AndroidFileSetStorage(context.getDataManager().getDataStorageRoot(), "libs_packaging"); + boolean doneSomething = false; - try { - boolean doneSomething = false; - for (Module module : chunk.getModules()) { - final AndroidFacet facet = AndroidJpsUtil.getFacet(module); - if (facet == null || !facet.isLibrary()) { + for (Module module : chunk.getModules()) { + final AndroidFacet facet = AndroidJpsUtil.getFacet(module); + if (facet == null || !facet.isLibrary()) { + continue; + } + + final ProjectPaths projectPaths = context.getProjectPaths(); + final File outputDirectoryForPackagedFiles = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(projectPaths, module); + + if (outputDirectoryForPackagedFiles == null) { + context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle + .message("android.jps.errors.output.dir.not.specified", module.getName()))); + success = false; + continue; + } + + final File classesDir = projectPaths.getModuleOutputDir(module, false); + if (classesDir == null || !classesDir.isDirectory()) { + continue; + } + + if (context.isMake()) { + final Set dirtyOutputDirs = context.getUserData(AndroidDexBuilder.DIRTY_OUTPUT_DIRS); + assert dirtyOutputDirs != null; + if (!dirtyOutputDirs.contains(classesDir.getPath())) { continue; } - - final ProjectPaths projectPaths = context.getProjectPaths(); - final File outputDirectoryForPackagedFiles = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(projectPaths, module); - - if (outputDirectoryForPackagedFiles == null) { - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle - .message("android.jps.errors.output.dir.not.specified", module.getName()))); - success = false; - continue; - } - - final File classesDir = projectPaths.getModuleOutputDir(module, false); - if (classesDir == null || !classesDir.isDirectory()) { - continue; - } - - final Set subdirs = new HashSet(); - AndroidJpsUtil.addSubdirectories(classesDir, subdirs); - - final AndroidFileSetState newState = new AndroidFileSetState(subdirs, AndroidJpsUtil.CLASSES_AND_JARS_FILTER, true); - final AndroidFileSetState oldState = storage.getState(module.getName()); - - if (oldState != null && oldState.equalsTo(newState)) { - continue; - } - - if (subdirs.size() > 0) { - context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.library.packaging", module.getName()))); - final File outputJarFile = new File(outputDirectoryForPackagedFiles, AndroidCommonUtils.CLASSES_JAR_FILE_NAME); - doneSomething = true; - try { - AndroidCommonUtils.packClassFilesIntoJar(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.toStringArray(subdirs), outputJarFile); - storage.update(module.getName(), newState); - } - catch (IOException e) { - AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME); - storage.update(module.getName(), null); - success = false; - } - } } - return success ? (doneSomething? ExitCode.OK : ExitCode.NOTHING_DONE) : ExitCode.ABORT; - } - finally { - storage.close(); + final Set subdirs = new HashSet(); + AndroidJpsUtil.addSubdirectories(classesDir, subdirs); + + if (subdirs.size() > 0) { + context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.library.packaging", module.getName()))); + final File outputJarFile = new File(outputDirectoryForPackagedFiles, AndroidCommonUtils.CLASSES_JAR_FILE_NAME); + doneSomething = true; + try { + AndroidCommonUtils.packClassFilesIntoJar(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.toStringArray(subdirs), outputJarFile); + } + catch (IOException e) { + AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME); + success = false; + } + } } + return success ? (doneSomething ? ExitCode.OK : ExitCode.NOTHING_DONE) : ExitCode.ABORT; } @Override diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index fe04ab7dd0b6..25bd4b10cd19 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -149,10 +149,10 @@ android.extract.package.choose.dest.apk=Choose destination APK file android.cannot.create.file.error=Cannot create file {0} android.cannot.create.dir.error=Cannot create directory {0} android.manifest.not.found.error=AndroidManifest.xml doesn't exist or has incorrect root tag -android.apt.settings.title=AAPT Compiler +android.apt.settings.title=R.java and Manifest.java files android.aidl.settings.title=AIDL Compiler android.generate.r.java.checkbox=Re&generate R.java file when resources are changed -android.dest.directory.title=De&stination directory\: +android.dest.directory.title=Director&y for generated files\: android.generate.r.java.by.res.dir=Use res&ource directory specified at "Structure" section android.use.custom.r.java.source.dir=Use custo&m resource directory\: android.regenerate.idl.when.changed.checkbox=Regenerate &Java files when AIDL files are changed @@ -170,7 +170,7 @@ android.run.avd.manager.action.text=AVD Manager android.choose.sdk.label=Please choose Android SDK location android.choose.sdk.title=Choose SDK copy.resources.from.artifacts.setting=R&un "process-resources" Maven task before Make -android.apk.settings.title=Android Packaging Compiler +android.apk.settings.title=Resources Packaging android.create.avd.dialog.sdcard.size=S&ize: android.create.avd.dialog.sdcard.file=&File: android.create.avd.dialog.sdcard.title=SDCard @@ -208,7 +208,7 @@ android.run.configuration.logcat.tab.title=Logcat android.facet.settings.apk.path.label=A&PK path: android.run.confguration.deploy.and.install.check.box=D&eploy application android.logcat.no.android.facets.error=There is no Android facets in the project -android.facet.settings.compile.resources.by.ide=&Compile resources by IDE +android.facet.settings.compile.resources.by.ide=&Generate by IDE android.keystore.password.label=Pa&ssword: android.keystore.confirm.password.label=C&onfirm: android.export.package.new.key.alias.label=&Alias: diff --git a/plugins/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java b/plugins/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java index 59953140d929..f34f27eb10df 100644 --- a/plugins/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java @@ -17,7 +17,6 @@ package org.jetbrains.android.actions; import com.android.ddmlib.AndroidDebugBridge; import com.intellij.facet.ProjectFacetManager; -import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -58,7 +57,6 @@ public class AndroidConnectDebuggerAction extends AnAction { super.update(e); final Project project = e.getData(PlatformDataKeys.PROJECT); e.getPresentation().setVisible(project != null && - ActionPlaces.MAIN_TOOLBAR.equals(e.getPlace()) && ProjectFacetManager.getInstance(project).getFacets(AndroidFacet.ID).size() > 0); } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java index 19a5c589b0ac..504790bdc735 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java @@ -54,10 +54,8 @@ public class AndroidAutogenerator { private static boolean toRun(@NotNull AndroidAutogeneratorMode mode, @NotNull AndroidFacet facet) { switch (mode) { case AAPT: - return facet.getConfiguration().REGENERATE_R_JAVA && - AndroidAptCompiler.isToCompileModule(facet.getModule(), facet.getConfiguration()); + return AndroidAptCompiler.isToCompileModule(facet.getModule(), facet.getConfiguration()); case AIDL: - return facet.getConfiguration().REGENERATE_JAVA_BY_AIDL; case RENDERSCRIPT: case BUILDCONFIG: return true; diff --git a/plugins/android/src/org/jetbrains/android/dom/attrs/AttributeDefinition.java b/plugins/android/src/org/jetbrains/android/dom/attrs/AttributeDefinition.java index eb9ba6db9eb0..4ec574107fbd 100644 --- a/plugins/android/src/org/jetbrains/android/dom/attrs/AttributeDefinition.java +++ b/plugins/android/src/org/jetbrains/android/dom/attrs/AttributeDefinition.java @@ -68,12 +68,7 @@ public class AttributeDefinition { } public void addDocValue(String docValue) { - if (myDocValue == null) { - myDocValue = docValue; - } - else { - myDocValue += "\n" + docValue; - } + myDocValue = docValue; } @Override diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java index f343797da791..6cb9d0f20d53 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java @@ -46,7 +46,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ModuleRootAdapter; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; @@ -449,12 +452,10 @@ public class AndroidFacet extends Facet { AndroidCompileUtil.collectAllResources(AndroidFacet.this, resourceSet); myListener.setResourceSet(resourceSet); - if (getConfiguration().REGENERATE_R_JAVA && AndroidAptCompiler.isToCompileModule(module, getConfiguration())) { + if (AndroidAptCompiler.isToCompileModule(module, getConfiguration())) { AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AAPT); } - if (getConfiguration().REGENERATE_JAVA_BY_AIDL) { - AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AIDL); - } + AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AIDL); AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.RENDERSCRIPT); AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.BUILDCONFIG); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java index 5bffd531bfed..350ba76c09e4 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java @@ -65,10 +65,6 @@ public class AndroidFacetConfiguration implements FacetConfiguration { public List RES_OVERLAY_FOLDERS = Arrays.asList("/res-overlay"); - public boolean REGENERATE_R_JAVA = true; - - public boolean REGENERATE_JAVA_BY_AIDL = true; - public boolean USE_CUSTOM_APK_RESOURCE_FOLDER = false; public String CUSTOM_APK_RESOURCE_FOLDER = ""; diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form index ec501111512b..c576dd02c28f 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form @@ -115,7 +115,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -156,52 +156,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -210,54 +172,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -265,18 +192,10 @@ - + - - - - - - - - @@ -299,42 +218,120 @@ - + - + - + - + - + + + + + + + + + + - + - + - + + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index c0fdabd8e656..10d4fde3fc36 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -78,8 +78,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { private JRadioButton myUseAptResDirectoryFromPathRadio; private JRadioButton myUseCustomSourceDirectoryRadio; private TextFieldWithBrowseButton myCustomAptSourceDirField; - private JCheckBox myGenerateRJavaWhenChanged; - private JCheckBox myGenerateIdlWhenChanged; private JCheckBox myIsLibraryProjectCheckbox; private JPanel myAaptCompilerPanel; private JCheckBox myGenerateUnsignedApk; @@ -233,24 +231,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { return file.isDirectory() || "apk".equals(file.getExtension()); } }); - - myGenerateIdlWhenChanged.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final boolean enabled = myGenerateIdlWhenChanged.isSelected(); - myAidlGenPathLabel.setEnabled(enabled); - myAidlGenPathField.setEnabled(enabled); - } - }); - - myGenerateRJavaWhenChanged.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final boolean enabled = myGenerateRJavaWhenChanged.isSelected(); - myRGenPathLabel.setEnabled(enabled); - myRGenPathField.setEnabled(enabled); - } - }); } private void updateAptPanel() { @@ -315,14 +295,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { return true; } - if (myGenerateRJavaWhenChanged.isSelected() != myConfiguration.REGENERATE_R_JAVA) { - return true; - } - - if (myGenerateIdlWhenChanged.isSelected() != myConfiguration.REGENERATE_JAVA_BY_AIDL) { - return true; - } - if (myUseCustomSourceDirectoryRadio.isSelected() != myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER) { return true; } @@ -487,16 +459,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { } myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER = useCustomAptSrc; - if (myConfiguration.REGENERATE_R_JAVA != myGenerateRJavaWhenChanged.isSelected()) { - runApt = true; - } - myConfiguration.REGENERATE_R_JAVA = myGenerateRJavaWhenChanged.isSelected(); - - if (myConfiguration.REGENERATE_JAVA_BY_AIDL != myGenerateIdlWhenChanged.isSelected()) { - runIdl = true; - } - myConfiguration.REGENERATE_JAVA_BY_AIDL = myGenerateIdlWhenChanged.isSelected(); - String absAptSourcePath = myCustomAptSourceDirField.getText().trim(); if (useCustomAptSrc) { if (absAptSourcePath.length() == 0) { @@ -513,12 +475,10 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myConfiguration.CUSTOM_APK_RESOURCE_FOLDER = relPath != null ? '/' + relPath : ""; } - runApt = runApt && myConfiguration.REGENERATE_R_JAVA && AndroidAptCompiler.isToCompileModule(myContext.getModule(), myConfiguration); - runIdl = runIdl && myConfiguration.REGENERATE_JAVA_BY_AIDL; + runApt = runApt && AndroidAptCompiler.isToCompileModule(myContext.getModule(), myConfiguration); if (runApt || runIdl) { final Module module = myContext.getModule(); - final Project project = module.getProject(); if (runApt) { AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AAPT, true); @@ -590,14 +550,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab { final int sdkToolsRevision = platform != null ? platform.getSdkData().getSdkToolsRevision() : -1; myIncludeSystemProguardFileCheckBox.setVisible(AndroidCommonUtils.isIncludingInProguardSupported(sdkToolsRevision)); - myGenerateRJavaWhenChanged.setSelected(configuration.REGENERATE_R_JAVA); - myRGenPathLabel.setEnabled(configuration.REGENERATE_R_JAVA); - myRGenPathField.setEnabled(configuration.REGENERATE_R_JAVA); - - myGenerateIdlWhenChanged.setSelected(configuration.REGENERATE_JAVA_BY_AIDL); - myAidlGenPathLabel.setEnabled(configuration.REGENERATE_JAVA_BY_AIDL); - myAidlGenPathField.setEnabled(configuration.REGENERATE_JAVA_BY_AIDL); - myUseCustomSourceDirectoryRadio.setSelected(configuration.USE_CUSTOM_APK_RESOURCE_FOLDER); myUseAptResDirectoryFromPathRadio.setSelected(!configuration.USE_CUSTOM_APK_RESOURCE_FOLDER); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java index 6a67ea9fac2e..40f84fa2a1e0 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java @@ -216,9 +216,7 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { final List modes = new ArrayList(); - if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && - (myFacet.getConfiguration().REGENERATE_R_JAVA && (gp == resourceDir || - manifestFile == file))) { + if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && (gp == resourceDir || manifestFile == file)) { final Manifest manifest = myFacet.getManifest(); final String aPackage = manifest != null ? manifest.getPackage().getValue() : null; @@ -230,7 +228,7 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { modes.add(AndroidAutogeneratorMode.AAPT); } - if (myFacet.getConfiguration().REGENERATE_JAVA_BY_AIDL && file.getFileType() == AndroidIdlFileType.ourFileType) { + if (file.getFileType() == AndroidIdlFileType.ourFileType) { VirtualFile sourceRoot = findSourceRoot(myModule, file); if (sourceRoot != null && AndroidRootUtil.getAidlGenDir(myFacet) != sourceRoot) { modes.add(AndroidAutogeneratorMode.AIDL); diff --git a/plugins/android/src/org/jetbrains/android/run/AvdComboBox.java b/plugins/android/src/org/jetbrains/android/run/AvdComboBox.java index 15a6955fac4f..1b518001fe7f 100644 --- a/plugins/android/src/org/jetbrains/android/run/AvdComboBox.java +++ b/plugins/android/src/org/jetbrains/android/run/AvdComboBox.java @@ -3,9 +3,11 @@ package org.jetbrains.android.run; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.IDevice; import com.android.sdklib.internal.avd.AvdInfo; -import com.intellij.execution.ExecutionBundle; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.ui.Messages; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.util.Alarm; @@ -14,7 +16,8 @@ import com.intellij.util.containers.HashSet; import org.jetbrains.android.actions.RunAndroidAvdManagerAction; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.sdk.AndroidPlatform; -import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.sdk.AndroidSdkAdditionalData; +import org.jetbrains.android.sdk.AndroidSdkType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,21 +45,9 @@ public abstract class AvdComboBox extends ComboboxWithBrowseButton { addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Module module = getModule(); - if (module == null) { - Messages.showErrorDialog(AvdComboBox.this, ExecutionBundle.message("module.not.specified.error.text")); - return; - } - - AndroidFacet facet = AndroidFacet.getInstance(module); - if (facet == null) { - Messages.showErrorDialog(AvdComboBox.this, AndroidBundle.message("no.facet.error", module.getName())); - return; - } - - final AndroidPlatform platform = facet.getConfiguration().getAndroidPlatform(); + final AndroidPlatform platform = findAndroidPlatform(); if (platform == null) { - Messages.showErrorDialog(AvdComboBox.this, AndroidBundle.message("android.compilation.error.specify.platform", module.getName())); + Messages.showErrorDialog(AvdComboBox.this, "Cannot find any configured Android SDK"); return; } @@ -98,7 +89,7 @@ public abstract class AvdComboBox extends ComboboxWithBrowseButton { final Module module = getModule(); final AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null; final String[] newAvds; - + if (facet != null) { final Set filteringSet = new HashSet(); if (myShowNotLaunchedOnly) { @@ -136,9 +127,44 @@ public abstract class AvdComboBox extends ComboboxWithBrowseButton { getComboBox().setModel(new DefaultComboBoxModel(newAvds)); getComboBox().setSelectedItem(selected); } - } @Nullable public abstract Module getModule(); + + @Nullable + private AndroidPlatform findAndroidPlatform() { + AndroidPlatform platform = findAndroidPlatformFromModule(); + if (platform != null) { + return platform; + } + + for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) { + if (sdk.getSdkType() instanceof AndroidSdkType) { + final SdkAdditionalData data = sdk.getSdkAdditionalData(); + if (data instanceof AndroidSdkAdditionalData) { + platform = ((AndroidSdkAdditionalData)data).getAndroidPlatform(); + if (platform != null) { + return platform; + } + } + } + } + return null; + } + + @Nullable + private AndroidPlatform findAndroidPlatformFromModule() { + Module module = getModule(); + if (module == null) { + return null; + } + + AndroidFacet facet = AndroidFacet.getInstance(module); + if (facet == null) { + return null; + } + + return facet.getConfiguration().getAndroidPlatform(); + } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionDialog.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionDialog.java index 503bb42774b1..2da5db5bb0db 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionDialog.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/importToCvs/CustomizeKeywordSubstitutionDialog.java @@ -90,7 +90,7 @@ public class CustomizeKeywordSubstitutionDialog extends DialogWrapper { } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return KeywordSubstitutionWrapper.KEYWORD_EXPANSION_LOCKER.toString(); } }; @@ -118,7 +118,7 @@ public class CustomizeKeywordSubstitutionDialog extends DialogWrapper { } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return getName(); } }; diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java index 27602c194bba..44a430482516 100644 --- a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java +++ b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java @@ -40,7 +40,6 @@ import git4idea.i18n.GitBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -421,7 +420,7 @@ public class GitMergeProvider implements MergeProvider2 { } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return GitBundle.message("merge.tool.column.status.modified"); } diff --git a/plugins/git4idea/src/git4idea/push/GitPushLog.java b/plugins/git4idea/src/git4idea/push/GitPushLog.java index 6e3b118e71c0..8c492ed2e770 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushLog.java +++ b/plugins/git4idea/src/git4idea/push/GitPushLog.java @@ -210,7 +210,6 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { } else { // we're looking to the breadthFirstEnumeration => all repository nodes have already been enumerated - // checking for null return; } } diff --git a/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java b/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java index 42700e67dd78..d0941f3f2b83 100644 --- a/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java +++ b/plugins/git4idea/src/git4idea/ui/GitCommitListPanel.java @@ -197,7 +197,7 @@ public class GitCommitListPanel extends JPanel implements TypeSafeDataProvider { } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return myMaxString; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 22b90249dd41..c08c07ba6f8a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -736,6 +736,7 @@ public class GroovyCompletionContributor extends CompletionContributor { public static void suggestVariableNames(PsiElement context, CompletionResultSet result) { final PsiElement parent = context.getParent(); + if (GroovyCompletionUtil.isWildcardCompletion(context)) return; if (parent instanceof GrVariable) { final GrVariable variable = (GrVariable) parent; if (context.equals(variable.getNameIdentifierGroovy())) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java index 267924e51aca..39f0eb9373a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java @@ -92,6 +92,8 @@ public class GroovyCompletionData { for (String keyword : addExtendsImplements(position)) { result.addElement(keyword(keyword, TailType.HUMBLE_SPACE_BEFORE_WORD)); } + + addExtendsForTypeParams(position, result); registerControlCompletion(position, result); @@ -143,6 +145,12 @@ public class GroovyCompletionData { } } + private static void addExtendsForTypeParams(PsiElement position, CompletionResultSet result) { + if (GroovyCompletionUtil.isWildcardCompletion(position)) { + addKeywords(result, true, PsiKeyword.EXTENDS, PsiKeyword.SUPER); + } + } + private static boolean isAfterForParameter(PsiElement position) { ElementPattern forParameter = psiElement().withParents(GrParameter.class, GrTraditionalForClause.class, GrForStatement.class); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java index 82048e78511f..007f387c176a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java @@ -46,6 +46,7 @@ import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.formatter.GeeseUtil; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; @@ -472,4 +473,19 @@ public class GroovyCompletionUtil { return true; } + /* + we are here: foo(List ... + */ + public static boolean isWildcardCompletion(PsiElement position) { + PsiElement prev = GeeseUtil.getPreviousNonWhitespaceToken(position); + if (prev instanceof PsiErrorElement) prev = GeeseUtil.getPreviousNonWhitespaceToken(prev); + + if (prev == null || prev.getNode().getElementType() != mQUESTION) return false; + + final PsiElement pprev = GeeseUtil.getPreviousNonWhitespaceToken(prev); + if (pprev == null) return false; + + final IElementType t = pprev.getNode().getElementType(); + return t == mLT || t == mCOMMA; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java index 379274b22dcc..05dd086f3e99 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java @@ -45,7 +45,7 @@ public class ParameterDeclaration implements GroovyElementTypes { PsiBuilder.Marker rb = builder.mark(); - final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder); + final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, true); if (result == ReferenceElement.ReferenceElementResult.fail && !hasModifiers) { rb.drop(); @@ -85,7 +85,7 @@ public class ParameterDeclaration implements GroovyElementTypes { PsiBuilder.Marker rb = builder.mark(); - final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder); + final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, false); if (mIDENT.equals(builder.getTokenType()) || (mTRIPLE_DOT.equals(builder.getTokenType()))) { rb.drop(); @@ -134,7 +134,7 @@ public class ParameterDeclaration implements GroovyElementTypes { typeCount++; rb.drop(); rb = builder.mark(); - final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder); + final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, false); if (result == ReferenceElement.ReferenceElementResult.fail && ParserUtils.lookAhead(builder, mBOR)) { builder.error(GroovyBundle.message("type.expected")); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java index 1578753363be..16328d8f46ff 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java @@ -71,7 +71,7 @@ public class ForStatement implements GroovyElementTypes { boolean isBuiltInType = TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()); PsiBuilder.Marker typeSpec = builder.mark(); - TypeSpec.parseStrict(builder); + TypeSpec.parseStrict(builder, false); if (builder.getTokenType() == mIDENT || isBuiltInType) { typeSpec.drop(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java index de2b17872776..1b2b941a5924 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/UnaryExpressionNotPlusMinus.java @@ -60,7 +60,7 @@ public class UnaryExpressionNotPlusMinus implements GroovyElementTypes { } private static boolean runPostfix(PsiBuilder builder, GroovyParser parser, boolean runPostfixIfFail) { - return runPostfixIfFail ? PostfixExpression.parse(builder, parser) : false; + return runPostfixIfFail && PostfixExpression.parse(builder, parser); } private static ReferenceElement.ReferenceElementResult parseTypeCast(PsiBuilder builder) { @@ -70,7 +70,7 @@ public class UnaryExpressionNotPlusMinus implements GroovyElementTypes { return fail; } if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType()) || mIDENT.equals(builder.getTokenType())) { - final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder); + final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder, true); if (result == fail) { marker.rollbackTo(); return fail; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeArguments.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeArguments.java index 485f322b3852..06780528fb79 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeArguments.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeArguments.java @@ -77,9 +77,11 @@ public class TypeArguments implements GroovyElementTypes { marker.rollbackTo(); return false; } + else { + builder.error(GroovyBundle.message("gt.expected")); + } } - marker.done(TYPE_ARGUMENTS); return true; } @@ -91,13 +93,7 @@ public class TypeArguments implements GroovyElementTypes { ParserUtils.getToken(builder, mQUESTION); if (ParserUtils.getToken(builder, kSUPER) || ParserUtils.getToken(builder, kEXTENDS)) { ParserUtils.getToken(builder, mNLS); - - //todo: check for upper case type specification - if (TypeSpec.parse(builder, false, false) == fail) { - taMarker.rollbackTo(); - return false; - } - + TypeSpec.parse(builder, false, false); ParserUtils.getToken(builder, mNLS); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java index b886d15515a4..7f62ed172e3f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/types/TypeSpec.java @@ -22,8 +22,10 @@ import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; -import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.*; -import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.ReferenceElementResult.*; +import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.ReferenceElementResult; +import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.ReferenceElementResult.fail; +import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.ReferenceElementResult.mustBeType; +import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement.parseReferenceElement; /** * @autor: Dmitry.Krasilschikov @@ -114,11 +116,12 @@ public class TypeSpec implements GroovyElementTypes { * @param builder * @return */ - public static ReferenceElementResult parseStrict(PsiBuilder builder) { + public static ReferenceElementResult parseStrict(PsiBuilder builder, boolean expressionPossible) { if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) { return parseBuiltInTypeStrict(builder); - } else if (builder.getTokenType() == mIDENT) { - return parseClassOrInterfaceTypeStrict(builder); + } + else if (builder.getTokenType() == mIDENT) { + return parseClassOrInterfaceTypeStrict(builder, expressionPossible); } return fail; } @@ -171,11 +174,11 @@ public class TypeSpec implements GroovyElementTypes { * @param builder * @return */ - private static ReferenceElementResult parseClassOrInterfaceTypeStrict(PsiBuilder builder) { + private static ReferenceElementResult parseClassOrInterfaceTypeStrict(PsiBuilder builder, boolean expressionPossible) { PsiBuilder.Marker arrMarker = builder.mark(); PsiBuilder.Marker typeElementMarker = builder.mark(); - final ReferenceElementResult result = parseReferenceElement(builder); + final ReferenceElementResult result = parseReferenceElement(builder, false, expressionPossible); if (result == fail) { typeElementMarker.drop(); arrMarker.rollbackTo(); @@ -185,9 +188,9 @@ public class TypeSpec implements GroovyElementTypes { typeElementMarker.done(CLASS_TYPE_ELEMENT); if (mLBRACK.equals(builder.getTokenType())) { - return declarationBracketsParseStrict(builder, arrMarker)? mustBeType: fail; - } else { -// arrMarker.done(CLASS_TYPE_ELEMENT); + return declarationBracketsParseStrict(builder, arrMarker) ? mustBeType : fail; + } + else { arrMarker.drop(); return result; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 7bc36a393198..1c920224e894 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -751,7 +751,7 @@ public class PsiUtil { } @Nullable - public static PsiElement getPrevNonSpace(final PsiElement elem) { + public static PsiElement getPrevNonSpace(@NotNull final PsiElement elem) { PsiElement prevSibling = elem.getPrevSibling(); while (prevSibling instanceof PsiWhiteSpace) { prevSibling = prevSibling.getPrevSibling(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 8c50592d29a6..fbfd5b92c939 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -1304,4 +1304,17 @@ def foo(Integer a) { ''') } + void testSuperExtendsInTypeParams() { + myFixture.configureByText("_.groovy", '''\ +def foo(List)'''); + myFixture.complete(CompletionType.BASIC); + assertOrderedEquals(myFixture.lookupElementStrings, "extends", "super"); + } + + void testSuperExtendsInTypeParams2() { + myFixture.configureByText("_.groovy", '''\ +def foo(List> list)'''); + myFixture.complete(CompletionType.BASIC); + assertOrderedEquals(myFixture.lookupElementStrings, "extends", "super"); + } } \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index af2a3127887d..4b11cb43148b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -20,12 +20,15 @@ import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.roots.DependencyScope; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.model.MavenConstants; import org.jetbrains.idea.maven.project.*; import org.jetbrains.idea.maven.utils.MavenUtil; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; import java.util.List; import java.util.Map; @@ -65,6 +68,7 @@ public class MavenModuleImporter { configFolders(); configDependencies(); configLanguageLevel(); + configEncoding(); } public void preConfigFacets() { @@ -138,6 +142,20 @@ public class MavenModuleImporter { return DependencyScope.COMPILE; } + private void configEncoding() { + if (Boolean.parseBoolean(System.getProperty("maven.disable.encode.import"))) return; + + String encoding = myMavenProject.getEncoding(); + if (encoding != null) { + try { + EncodingManager.getInstance().setEncoding(myMavenProject.getDirectoryFile(), Charset.forName(encoding)); + } + catch (UnsupportedCharsetException ignored) { + + } + } + } + private void configLanguageLevel() { final LanguageLevel level = LanguageLevel.parse(myMavenProject.getSourceLevel()); if (level != null) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java index 5f3f6e99157a..b49f872d8fcd 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java @@ -748,6 +748,19 @@ public class MavenProject { return null; } + @Nullable + public String getEncoding() { + String encoding = myState.myProperties.getProperty("project.build.sourceEncoding"); + if (encoding != null) return encoding; + + Element pluginConfiguration = getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"); + if (pluginConfiguration != null) { + return pluginConfiguration.getChildTextTrim("encoding"); + } + + return null; + } + @Nullable public String getSourceLevel() { return getCompilerLevel("source"); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy new file mode 100644 index 000000000000..8a296154799d --- /dev/null +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing + +import org.jetbrains.idea.maven.MavenImportingTestCase +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VfsUtil + +/** + * @author Sergey Evdokimov + */ +class EncodingImportingTest extends MavenImportingTestCase { + + public void testEncodingDefinedByProperty() { + byte[] text = [-12, -59, -53, -45, -44] // Russian text in koi8-r encoding. + + VirtualFile file = createProjectSubFile("src/main/resources/A.txt") + file.setBinaryContent(text) + + importProject(""" +test +project +1 + + +koi8-r + +""") + + def loadedText = VfsUtil.loadText(file) + + assert loadedText == new String(text, "koi8-r") + } + + public void testEncodingDefinedByPluginConfig() { + byte[] text = [-12, -59, -53, 45, -44] // Russian text in koi8-r encoding. + + VirtualFile file = createProjectSubFile("src/main/resources/A.txt") + file.setBinaryContent(text) + + importProject(""" +test +project +1 + + + + + maven-resources-plugin + + koi8-r + + + + +""") + + def loadedText = VfsUtil.loadText(file) + + assert loadedText == new String(text, "koi8-r") + } + +} diff --git a/plugins/svn4idea/lib/sqljet.jar b/plugins/svn4idea/lib/sqljet.jar index 41f9548a0e64..0bb5b2fd98e1 100644 Binary files a/plugins/svn4idea/lib/sqljet.jar and b/plugins/svn4idea/lib/sqljet.jar differ diff --git a/plugins/svn4idea/lib/svnkit-javahl.jar b/plugins/svn4idea/lib/svnkit-javahl.jar index ba983031e920..b19c1cef3f55 100644 Binary files a/plugins/svn4idea/lib/svnkit-javahl.jar and b/plugins/svn4idea/lib/svnkit-javahl.jar differ diff --git a/plugins/svn4idea/lib/svnkit-javahl16.zip b/plugins/svn4idea/lib/svnkit-javahl16.zip index ac7ca0211e5a..fe72b72541ff 100644 Binary files a/plugins/svn4idea/lib/svnkit-javahl16.zip and b/plugins/svn4idea/lib/svnkit-javahl16.zip differ diff --git a/plugins/svn4idea/lib/svnkit.jar b/plugins/svn4idea/lib/svnkit.jar index 731468bc8ad0..436aff99484d 100644 Binary files a/plugins/svn4idea/lib/svnkit.jar and b/plugins/svn4idea/lib/svnkit.jar differ diff --git a/plugins/svn4idea/lib/svnkitsrc.zip b/plugins/svn4idea/lib/svnkitsrc.zip index 99c2dab4ede6..f5992f24a3e3 100644 Binary files a/plugins/svn4idea/lib/svnkitsrc.zip and b/plugins/svn4idea/lib/svnkitsrc.zip differ diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index e58f6ca2b57f..c6a017189e63 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -48,10 +48,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; -import org.tmatesoft.svn.core.SVNCancelException; -import org.tmatesoft.svn.core.SVNCommitInfo; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.wc.*; import javax.swing.*; @@ -212,7 +209,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { SVNCommitPacket[] commitPackets = null; SVNCommitInfo[] results; try { - commitPackets = committer.doCollectCommitItems(pathsToCommit, keepLocks, force, recursive, true); + commitPackets = committer.doCollectCommitItems(pathsToCommit, keepLocks, force, SVNDepth.EMPTY, true, null); results = committer.doCommit(commitPackets, keepLocks, comment); commitPackets = null; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java index 229578f50a8c..2d32622e38bf 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java @@ -803,7 +803,7 @@ public class SvnHistoryProvider } @Override - public String getMaxStringValue(JTable table) { + public String getMaxStringValue() { return SvnBundle.message("copy.column.title"); } diff --git a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml index e63d9004a977..54e20de62ffb 100644 --- a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml +++ b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml @@ -16,11 +16,17 @@ - + - + + + + + + diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/Property.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/Property.java index 326058e67bad..7a004880790b 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/Property.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/Property.java @@ -16,6 +16,7 @@ package com.intellij.designer.propertyTable; import com.intellij.designer.model.RadComponent; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,6 +43,7 @@ public abstract class Property { } public abstract Property createForNewPresentation(@Nullable Property parent, @NotNull String name); + ////////////////////////////////////////////////////////////////////////////////////////// // // Hierarchy @@ -135,4 +137,20 @@ public abstract class Property { @Nullable public abstract PropertyEditor getEditor(); + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // Javadoc + // + ////////////////////////////////////////////////////////////////////////////////////////// + + @Nullable + public PsiElement getJavadocElement() { + return null; + } + + @Nullable + public String getJavadocText() { + return null; + } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java index 397f6b5ab633..f22f320262b2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java @@ -87,8 +87,6 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi } }); - // TODO: ShowJavadocAction - // TODO: Updates UI after LAF updated } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java index 7aefd5b82cff..54c7891b27ec 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java @@ -17,6 +17,7 @@ package com.intellij.designer.propertyTable; import com.intellij.designer.DesignerBundle; import com.intellij.designer.propertyTable.actions.IPropertyTableAction; +import com.intellij.designer.propertyTable.actions.ShowJavadoc; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.impl.ActionButton; import com.intellij.ui.IdeBorderFactory; @@ -43,18 +44,25 @@ public final class PropertyTablePanel extends JPanel implements ListSelectionLis add(new JLabel(DesignerBundle.message("designer.properties.title")), new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 0), 0, 0)); - ActionGroup actionGroup = (ActionGroup)ActionManager.getInstance().getAction("UIDesigner.PropertyTable"); + ActionManager actionManager = ActionManager.getInstance(); + + AnAction quickJavadocAction = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC); + new ShowJavadoc().registerCustomShortcutSet(quickJavadocAction.getShortcutSet(), myPropertyTable); + + ActionGroup actionGroup = (ActionGroup)actionManager.getAction("UIDesigner.PropertyTable"); PopupHandler.installPopupHandler(myPropertyTable, actionGroup, ActionPlaces.GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP, - ActionManager.getInstance()); + actionManager); myActions = actionGroup.getChildren(null); for (int i = 0; i < myActions.length; i++) { AnAction action = myActions[i]; - add(new ActionButton(action, action.getTemplatePresentation(), ActionPlaces.UNKNOWN, ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE), - new GridBagConstraints(i + 1, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, - new Insets(2, 0, 2, i == myActions.length - 1 ? 2 : 0), 0, 0)); + if (!(action instanceof Separator)) { + add(new ActionButton(action, action.getTemplatePresentation(), ActionPlaces.UNKNOWN, ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE), + new GridBagConstraints(i + 1, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, + new Insets(2, 0, 2, i == myActions.length - 1 ? 2 : 0), 0, 0)); + } } myPropertyTable.getSelectionModel().addListSelectionListener(this); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java new file mode 100644 index 000000000000..c11a585ba6dc --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.designer.propertyTable.actions; + +import com.intellij.codeInsight.documentation.DocumentationComponent; +import com.intellij.codeInsight.documentation.DocumentationManager; +import com.intellij.designer.DesignerBundle; +import com.intellij.designer.DesignerToolWindowManager; +import com.intellij.designer.propertyTable.Property; +import com.intellij.designer.propertyTable.PropertyTable; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.ui.awt.RelativePoint; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class ShowJavadoc extends AnAction implements IPropertyTableAction { + public ShowJavadoc() { + Presentation presentation = getTemplatePresentation(); + String text = DesignerBundle.message("designer.properties.show.javadoc"); + presentation.setText(text); + presentation.setDescription(text); + presentation.setIcon(IconLoader.getIcon("/actions/help.png")); + } + + @Override + public void update(AnActionEvent e) { + PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable(); + setEnabled(table, e.getPresentation()); + } + + @Override + public void update(PropertyTable table) { + setEnabled(table, getTemplatePresentation()); + } + + private static void setEnabled(PropertyTable table, Presentation presentation) { + Property property = table.getSelectionProperty(); + presentation.setEnabled(property != null && (property.getJavadocElement() != null || !StringUtil.isEmpty(property.getJavadocText()))); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = e.getProject(); + DocumentationManager documentationManager = DocumentationManager.getInstance(project); + final DocumentationComponent component = new DocumentationComponent(documentationManager); + + final PropertyTable table = DesignerToolWindowManager.getInstance(project).getPropertyTable(); + final Property property = table.getSelectionProperty(); + PsiElement javadocElement = property.getJavadocElement(); + + ActionCallback callback; + if (javadocElement == null) { + callback = new ActionCallback(); + component.setText(property.getJavadocText(), null, true); + } + else { + callback = documentationManager.queueFetchDocInfo(javadocElement, component); + } + + callback.doWhenProcessed(new Runnable() { + public void run() { + final JBPopup hint = + JBPopupFactory.getInstance().createComponentPopupBuilder(component, component) + .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false) + .setResizable(true) + .setMovable(true) + .setRequestFocus(true) + .setTitle(DesignerBundle.message("designer.properties.javadoc.title", property.getName())) + .createPopup(); + component.setHint(hint); + Disposer.register(hint, component); + hint.show(new RelativePoint(table.getParent(), new Point(0, 0))); + } + }); + + if (javadocElement == null) { + callback.setDone(); + } + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties b/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties index 089103a611d9..f105d74fd4cf 100644 --- a/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties +++ b/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties @@ -7,6 +7,8 @@ command.set.property.value=Set Property Value designer.properties.title=Properties designer.properties.show.expert=Show expert properties +designer.properties.show.javadoc=Show Documentation +designer.properties.javadoc.title=Documentation for {0} property designer.properties.restore_default=Restore default value designer.properties.column1=Property designer.properties.column2=Value diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java index ff395f1acd04..9d114d27aad0 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java @@ -23,6 +23,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -113,7 +114,11 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat @NotNull public Set getRootsToWatch() { - return Collections.singleton(getExternalResourcesPath()); + final File path = new File(getExternalResourcesPath()); + if (!path.exists() && !path.mkdirs()) { + LOG.warn("Unable to create: " + path); + } + return Collections.singleton(path.getAbsolutePath()); } static class FetchingResourceIOException extends IOException { @@ -176,6 +181,7 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat final PsiManager psiManager = PsiManager.getInstance(project); ApplicationManager.getApplication().invokeAndWait(new Runnable() { public void run() { + @SuppressWarnings("deprecation") final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(FetchExtResourceAction.class); try { final String path = FileUtil.toSystemIndependentName(extResources.getAbsolutePath()); @@ -342,11 +348,14 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat int slashIndex = resourceUrl.lastIndexOf('/'); String resPath = extResourcesPath + File.separatorChar; - if (refname != null) { // resource is known under refname so need to save it + if (refname != null) { // resource is known under ref.name so need to save it resPath += refname; - int refnameSlashIndex = resPath.lastIndexOf('/'); - if (refnameSlashIndex != -1) { - new File(resPath.substring(0, refnameSlashIndex)).mkdirs(); + int refNameSlashIndex = resPath.lastIndexOf('/'); + if (refNameSlashIndex != -1) { + final File parent = new File(resPath.substring(0, refNameSlashIndex)); + if (!parent.mkdirs() || !parent.exists()) { + LOG.warn("Unable to create: " + parent); + } } } else { @@ -355,8 +364,7 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat final int lastDoPosInResourceUrl = resourceUrl.lastIndexOf('.', slashIndex); if (lastDoPosInResourceUrl == -1 || - FileTypeManager.getInstance().getFileTypeByExtension(resourceUrl.substring(lastDoPosInResourceUrl + 1)) == StdFileTypes.UNKNOWN - ) { + FileTypeManager.getInstance().getFileTypeByExtension(resourceUrl.substring(lastDoPosInResourceUrl + 1)) == FileTypes.UNKNOWN) { // remote url does not contain file with extension resPath += "." + StdFileTypes.XML.getDefaultExtension(); } diff --git a/xml/impl/src/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java b/xml/impl/src/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java index e0b154aaa118..1dd333a41c66 100644 --- a/xml/impl/src/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java +++ b/xml/impl/src/com/intellij/xml/impl/dtd/XmlNSDescriptorImpl.java @@ -29,7 +29,7 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.xml.*; import com.intellij.xml.XmlElementDescriptor; -import com.intellij.xml.XmlNSDescriptor; +import com.intellij.xml.XmlNSDescriptorEx; import com.intellij.xml.impl.ExternalDocumentValidator; import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NotNull; @@ -40,7 +40,7 @@ import java.util.*; /** * @author Mike */ -public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator, DumbAware { +public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator, DumbAware { private XmlElement myElement; private XmlFile myDescriptorFile; @@ -196,4 +196,9 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator