Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Dmitry Trofimov
2010-08-02 21:17:16 +04:00
69 changed files with 2126 additions and 893 deletions
@@ -43,11 +43,18 @@ public class ArchiveAntCopyInstructionCreator implements AntCopyInstructionCreat
}
@NotNull
public AntCopyInstructionCreator subFolder(String directoryName) {
public AntCopyInstructionCreator subFolder(@NotNull String directoryName) {
return new ArchiveAntCopyInstructionCreator(myPrefix + "/" + directoryName);
}
public Generator createSubFolderCommand(String directoryName) {
public Generator createSubFolderCommand(@NotNull String directoryName) {
return null;
}
@NotNull
@Override
public Generator createExtractedDirectoryInstruction(@NotNull String jarPath, @NotNull String pathInJar) {
final String pattern = pathInJar.length() == 0 ? null : pathInJar + "**";
return ZipFileSet.createUnpackedSet(jarPath, pathInJar, true, pattern);
}
}
@@ -17,9 +17,7 @@ package com.intellij.compiler.ant.artifacts;
import com.intellij.compiler.ant.Generator;
import com.intellij.compiler.ant.Tag;
import com.intellij.compiler.ant.taskdefs.Copy;
import com.intellij.compiler.ant.taskdefs.FileSet;
import com.intellij.compiler.ant.taskdefs.Mkdir;
import com.intellij.compiler.ant.taskdefs.*;
import com.intellij.packaging.elements.AntCopyInstructionCreator;
import org.jetbrains.annotations.NotNull;
@@ -50,11 +48,23 @@ public class DirectoryAntCopyInstructionCreator implements AntCopyInstructionCre
}
@NotNull
public AntCopyInstructionCreator subFolder(String directoryName) {
public AntCopyInstructionCreator subFolder(@NotNull String directoryName) {
return new DirectoryAntCopyInstructionCreator(myOutputDirectory + "/" + directoryName);
}
public Generator createSubFolderCommand(String directoryName) {
public Generator createSubFolderCommand(@NotNull String directoryName) {
return new Mkdir(myOutputDirectory + "/" + directoryName);
}
@NotNull
@Override
public Generator createExtractedDirectoryInstruction(@NotNull String jarPath, @NotNull String pathInJar) {
final Unzip unzip = new Unzip(jarPath, myOutputDirectory);
if (pathInJar.length() > 0) {
final PatternSet patterns = new PatternSet(null);
patterns.add(new Include(pathInJar + "**"));
unzip.add(patterns);
}
return unzip;
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.graph.CachingSemiGraph;
import com.intellij.util.graph.DFSTBuilder;
@@ -159,8 +160,14 @@ public class JarsBuilder {
try {
final THashSet<String> writtenPaths = new THashSet<String>();
for (Pair<String, VirtualFile> pair : jar.getPackedFiles()) {
File file = VfsUtil.virtualToIoFile(pair.getSecond());
addFileToJar(jarOutputStream, file, pair.getFirst(), writtenPaths);
final VirtualFile sourceFile = pair.getSecond();
if (sourceFile.isInLocalFileSystem()) {
File file = VfsUtil.virtualToIoFile(sourceFile);
addFileToJar(jarOutputStream, file, pair.getFirst(), writtenPaths);
}
else {
extractFileAndAddToJar(jarOutputStream, sourceFile, pair.getFirst(), writtenPaths);
}
}
for (Pair<String, JarInfo> nestedJar : jar.getPackedJars()) {
@@ -178,9 +185,35 @@ public class JarsBuilder {
}
}
private void extractFileAndAddToJar(JarOutputStream jarOutputStream, VirtualFile sourceFile, String relativePath, THashSet<String> writtenPaths)
throws IOException {
relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath);
myContext.getProgressIndicator().setText2(relativePath);
if (!writtenPaths.add(relativePath)) return;
final BufferedInputStream input = ArtifactCompilerUtil.getJarEntryInputStream(sourceFile, myContext);
if (input == null) return;
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(ArtifactCompilerUtil.getJarFile(sourceFile).lastModified());
jarOutputStream.putNextEntry(entry);
FileUtil.copy(input, jarOutputStream);
jarOutputStream.closeEntry();
}
private void addFileToJar(final @NotNull JarOutputStream jarOutputStream, final @NotNull File file, @NotNull String relativePath,
final @NotNull THashSet<String> writtenPaths) throws IOException {
//todo[nik] check file exists?
if (!file.exists()) {
return;
}
relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath);
myContext.getProgressIndicator().setText2(relativePath);
ZipUtil.addFileToZip(jarOutputStream, file, relativePath, writtenPaths, myFileFilter);
}
private static String addParentDirectories(JarOutputStream jarOutputStream, THashSet<String> writtenPaths, String relativePath)
throws IOException {
while (relativePath.startsWith("/")) {
relativePath = relativePath.substring(1);
}
@@ -193,9 +226,7 @@ public class JarsBuilder {
}
i = relativePath.indexOf('/', i + 1);
}
myContext.getProgressIndicator().setText2(relativePath);
ZipUtil.addFileToZip(jarOutputStream, file, relativePath, writtenPaths, myFileFilter);
return relativePath;
}
private static void addEntry(final ZipOutputStream output, @NonNls final String relativePath) throws IOException {
@@ -320,6 +320,7 @@ public class ArtifactUtil {
boolean processSubstitutions) {
processPackagingElements(artifact, PackagingElementFactoryImpl.FILE_COPY_ELEMENT_TYPE, processor, context, processSubstitutions);
processPackagingElements(artifact, PackagingElementFactoryImpl.DIRECTORY_COPY_ELEMENT_TYPE, processor, context, processSubstitutions);
processPackagingElements(artifact, PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE, processor, context, processSubstitutions);
}
public static Collection<Trinity<Artifact, PackagingElementPath, String>> findContainingArtifactsWithOutputPaths(@NotNull final VirtualFile file, @NotNull Project project) {
@@ -417,8 +418,8 @@ public class ArtifactUtil {
ContainerUtil.addIfNotNull(fileCopyElement.findFile(), result);
}
}
else if (element instanceof DirectoryCopyPackagingElement) {
final VirtualFile sourceRoot = ((DirectoryCopyPackagingElement)element).findFile();
else if (element instanceof DirectoryCopyPackagingElement || element instanceof ExtractedDirectoryPackagingElement) {
final VirtualFile sourceRoot = ((FileOrDirectoryCopyPackagingElement<?>)element).findFile();
if (sourceRoot != null) {
ContainerUtil.addIfNotNull(sourceRoot.findFileByRelativePath(path), result);
}
@@ -0,0 +1,68 @@
/*
* Copyright 2000-2010 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.packaging.impl.compiler;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @author nik
*/
public class ArtifactCompilerUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.ArtifactCompilerUtil");
private ArtifactCompilerUtil() {
}
@Nullable
public static BufferedInputStream getJarEntryInputStream(VirtualFile sourceFile, final CompileContext context) throws IOException {
final String fullPath = sourceFile.getPath();
final int jarEnd = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
LOG.assertTrue(jarEnd != -1, fullPath);
String pathInJar = fullPath.substring(jarEnd + JarFileSystem.JAR_SEPARATOR.length());
String jarPath = fullPath.substring(0, jarEnd);
final ZipFile jarFile = new ZipFile(new File(FileUtil.toSystemDependentName(jarPath)));
final ZipEntry entry = jarFile.getEntry(pathInJar);
if (entry == null) {
context.addMessage(CompilerMessageCategory.ERROR, "Cannot extract '" + pathInJar + "' from '" + jarFile.getName() + "': entry not found", null, -1, -1);
return null;
}
return new BufferedInputStream(jarFile.getInputStream(entry)) {
@Override
public void close() throws IOException {
super.close();
jarFile.close();
}
};
}
public static File getJarFile(VirtualFile jarEntry) {
String fullPath = jarEntry.getPath();
return new File(FileUtil.toSystemDependentName(fullPath.substring(fullPath.indexOf(JarFileSystem.JAR_SEPARATOR))));
}
}
@@ -31,7 +31,7 @@ import com.intellij.openapi.deployment.DeploymentUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
@@ -53,9 +53,7 @@ import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.*;
import java.util.*;
/**
@@ -164,7 +162,7 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
private boolean doBuild(final List<Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState>> changedItems,
final Set<ArtifactCompilerCompileItem> processedItems,
final Set<String> writtenPaths, final Set<String> deletedJars) {
final @NotNull Set<String> writtenPaths, final Set<String> deletedJars) {
final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
final DeploymentUtil deploymentUtil = DeploymentUtil.getInstance();
@@ -188,20 +186,26 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
final Ref<IOException> exception = Ref.create(null);
new ReadAction() {
protected void run(final Result result) {
final File fromFile = VfsUtil.virtualToIoFile(sourceItem.getFile());
final VirtualFile sourceFile = sourceItem.getFile();
for (DestinationInfo destination : sourceItem.getDestinations()) {
if (destination instanceof ExplodedDestinationInfo) {
final ExplodedDestinationInfo explodedDestination = (ExplodedDestinationInfo)destination;
File toFile = new File(FileUtil.toSystemDependentName(explodedDestination.getOutputPath()));
if (fromFile.exists()) {
try {
deploymentUtil.copyFile(fromFile, toFile, myContext, writtenPaths, fileFilter);
try {
if (sourceFile.isInLocalFileSystem()) {
final File ioFromFile = VfsUtil.virtualToIoFile(sourceFile);
if (ioFromFile.exists()) {
deploymentUtil.copyFile(ioFromFile, toFile, myContext, writtenPaths, fileFilter);
}
}
catch (IOException e) {
exception.set(e);
return;
else {
extractFile(sourceFile, toFile, writtenPaths, fileFilter);
}
}
catch (IOException e) {
exception.set(e);
return;
}
}
else {
changedJars.add(((JarDestinationInfo)destination).getJarInfo());
@@ -254,6 +258,28 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
return true;
}
private void extractFile(VirtualFile sourceFile, File toFile, Set<String> writtenPaths, FileFilter fileFilter) throws IOException {
if (!writtenPaths.add(toFile.getPath())) {
return;
}
if (!FileUtil.createParentDirs(toFile)) {
myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot create directory for '" + toFile.getAbsolutePath() + "' file", null, -1, -1);
return;
}
final BufferedInputStream input = ArtifactCompilerUtil.getJarEntryInputStream(sourceFile, myContext);
if (input == null) return;
final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(toFile));
try {
FileUtil.copy(input, output);
}
finally {
input.close();
output.close();
}
}
private void onBuildStartedOrFinished(final boolean finished) throws Exception {
final Set<Artifact> artifacts = myContext.getUserData(ArtifactsCompiler.AFFECTED_ARTIFACTS);
if (artifacts != null) {
@@ -51,7 +51,7 @@ public class DirectoryCopyPackagingElement extends FileOrDirectoryCopyPackagingE
@NotNull ArtifactAntGenerationContext generationContext,
@NotNull ArtifactType artifactType) {
final String path = generationContext.getSubstitutedPath(myFilePath);
return Collections.singletonList((Generator)creator.createDirectoryContentCopyInstruction(path));
return Collections.singletonList(creator.createDirectoryContentCopyInstruction(path));
}
@Override
@@ -0,0 +1,80 @@
/*
* Copyright 2000-2010 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.packaging.impl.elements;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElementType;
import com.intellij.packaging.ui.ArtifactEditorContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public class ExtractedDirectoryElementType extends PackagingElementType<ExtractedDirectoryPackagingElement> {
public static final Icon EXTRACTED_FOLDER_ICON = IconLoader.getIcon("/nodes/extractedFolder.png");
ExtractedDirectoryElementType() {
super("extracted-dir", "Extracted Directory");
}
@Override
public Icon getCreateElementIcon() {
return EXTRACTED_FOLDER_ICON;
}
@Override
public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
return true;
}
@NotNull
public List<? extends ExtractedDirectoryPackagingElement> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
@NotNull CompositePackagingElement<?> parent) {
final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, true, true) {
@Override
public boolean isFileSelectable(VirtualFile file) {
if (file.isInLocalFileSystem() && file.isDirectory()) return false;
return super.isFileSelectable(file);
}
};
final FileChooserDialog chooser = FileChooserFactory.getInstance().createFileChooser(descriptor, context.getProject());
final VirtualFile[] files = chooser.choose(null, context.getProject());
final List<ExtractedDirectoryPackagingElement> list = new ArrayList<ExtractedDirectoryPackagingElement>();
for (VirtualFile file : files) {
final String fullPath = file.getPath();
final int jarEnd = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
list.add(new ExtractedDirectoryPackagingElement(fullPath.substring(0, jarEnd), fullPath.substring(jarEnd + 1)));
}
return list;
}
@NotNull
public ExtractedDirectoryPackagingElement createEmpty(@NotNull Project project) {
return new ExtractedDirectoryPackagingElement();
}
}
@@ -0,0 +1,116 @@
/*
* Copyright 2000-2010 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.packaging.impl.elements;
import com.intellij.compiler.ant.Generator;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.elements.*;
import com.intellij.packaging.impl.ui.ExtractedDirectoryPresentation;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingElementPresentation;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
public class ExtractedDirectoryPackagingElement extends FileOrDirectoryCopyPackagingElement<ExtractedDirectoryPackagingElement> {
private String myPathInJar;
public ExtractedDirectoryPackagingElement() {
super(PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE);
}
public ExtractedDirectoryPackagingElement(String jarPath, String pathInJar) {
super(PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE, jarPath);
myPathInJar = pathInJar;
if (!StringUtil.startsWithChar(myPathInJar, '/')) {
myPathInJar = "/" + myPathInJar;
}
if (!StringUtil.endsWithChar(myPathInJar, '/')) {
myPathInJar += "/";
}
}
@Override
public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
return new ExtractedDirectoryPresentation(this);
}
@Override
public VirtualFile findFile() {
final VirtualFile jarFile = super.findFile();
if (jarFile == null) return null;
final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jarFile);
if ("/".equals(myPathInJar)) return jarRoot;
return jarRoot != null ? jarRoot.findFileByRelativePath(myPathInJar) : null;
}
@Override
public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext,
@NotNull AntCopyInstructionCreator creator,
@NotNull ArtifactAntGenerationContext generationContext,
@NotNull ArtifactType artifactType) {
final String jarPath = generationContext.getSubstitutedPath(myFilePath);
return Collections.singletonList(creator.createExtractedDirectoryInstruction(jarPath, StringUtil.trimStart(myPathInJar, "/")));
}
@Override
public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
@NotNull PackagingElementResolvingContext resolvingContext,
@NotNull ArtifactIncrementalCompilerContext compilerContext,
@NotNull ArtifactType artifactType) {
final VirtualFile file = findFile();
if (file != null && file.isValid() && file.isDirectory()) {
creator.addDirectoryCopyInstructions(file);
}
}
@Override
public boolean isEqualTo(@NotNull PackagingElement<?> element) {
return element instanceof ExtractedDirectoryPackagingElement && super.isEqualTo(element)
&& Comparing.equal(myPathInJar, ((ExtractedDirectoryPackagingElement)element).getPathInJar());
}
@Override
public ExtractedDirectoryPackagingElement getState() {
return this;
}
@Override
public void loadState(ExtractedDirectoryPackagingElement state) {
myFilePath = state.getFilePath();
myPathInJar = state.getPathInJar();
}
@Attribute("path-in-jar")
public String getPathInJar() {
return myPathInJar;
}
public void setPathInJar(String pathInJar) {
myPathInJar = pathInJar;
}
}
@@ -58,7 +58,7 @@ public class FileCopyPackagingElement extends FileOrDirectoryCopyPackagingElemen
}
public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
return new FileCopyPresentation(myFilePath, getOutputFileName(), context);
return new FileCopyPresentation(myFilePath, getOutputFileName());
}
@Override
@@ -51,11 +51,12 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory {
public static final PackagingElementType<ArchivePackagingElement> ARCHIVE_ELEMENT_TYPE = new ArchiveElementType();
public static final PackagingElementType<FileCopyPackagingElement> FILE_COPY_ELEMENT_TYPE = new FileCopyElementType();
public static final PackagingElementType<DirectoryCopyPackagingElement> DIRECTORY_COPY_ELEMENT_TYPE = new DirectoryCopyElementType();
public static final PackagingElementType<ExtractedDirectoryPackagingElement> EXTRACTED_DIRECTORY_ELEMENT_TYPE = new ExtractedDirectoryElementType();
public static final PackagingElementType<ArtifactRootElement<?>> ARTIFACT_ROOT_ELEMENT_TYPE = new ArtifactRootElementType();
private static final PackagingElementType[] STANDARD_TYPES = {
DIRECTORY_ELEMENT_TYPE, ARCHIVE_ELEMENT_TYPE,
LibraryElementType.LIBRARY_ELEMENT_TYPE, ModuleOutputElementType.MODULE_OUTPUT_ELEMENT_TYPE,
ArtifactElementType.ARTIFACT_ELEMENT_TYPE, FILE_COPY_ELEMENT_TYPE, DIRECTORY_COPY_ELEMENT_TYPE
ArtifactElementType.ARTIFACT_ELEMENT_TYPE, FILE_COPY_ELEMENT_TYPE, DIRECTORY_COPY_ELEMENT_TYPE, EXTRACTED_DIRECTORY_ELEMENT_TYPE
};
@NotNull
@@ -253,6 +254,13 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory {
return createParentDirectories(relativeOutputPath, new DirectoryCopyPackagingElement(filePath));
}
@Override
@NotNull
public PackagingElement<?> createExtractedDirectoryWithParentDirectories(@NotNull String jarPath, @NotNull String pathInJar,
@NotNull String relativeOutputPath) {
return createParentDirectories(relativeOutputPath, new ExtractedDirectoryPackagingElement(jarPath, pathInJar));
}
@NotNull
@Override
public PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath) {
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2010 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.packaging.impl.ui;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.impl.elements.ExtractedDirectoryElementType;
import com.intellij.packaging.impl.elements.ExtractedDirectoryPackagingElement;
import com.intellij.packaging.ui.PackagingElementPresentation;
import com.intellij.packaging.ui.PackagingElementWeights;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class ExtractedDirectoryPresentation extends PackagingElementPresentation {
private final String myJarPath;
private final String myPathInJar;
private final VirtualFile myFile;
public ExtractedDirectoryPresentation(ExtractedDirectoryPackagingElement element) {
myFile = element.findFile();
myJarPath = element.getFilePath();
myPathInJar = element.getPathInJar();
}
public String getPresentableName() {
return PathUtil.getFileName(myJarPath) + myPathInJar;
}
public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
presentationData.setIcons(ExtractedDirectoryElementType.EXTRACTED_FOLDER_ICON);
final String parentPath = PathUtil.getParentPath(myJarPath);
if (myFile == null || !myFile.isDirectory()) {
mainAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
final VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(parentPath);
if (parentFile == null) {
commentAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
}
}
presentationData.addText("Unpacked '" + PathUtil.getFileName(myJarPath) + myPathInJar + "'", mainAttributes);
presentationData.addText(" (" + parentPath + ")", commentAttributes);
}
@Override
public int getWeight() {
return PackagingElementWeights.EXTRACTED_DIRECTORY;
}
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.impl.elements.FileCopyElementType;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingElementPresentation;
import com.intellij.packaging.ui.PackagingElementWeights;
import com.intellij.ui.SimpleTextAttributes;
@@ -33,12 +32,10 @@ import org.jetbrains.annotations.NotNull;
public class FileCopyPresentation extends PackagingElementPresentation {
private final String mySourcePath;
private final String myOutputFileName;
private final ArtifactEditorContext myContext;
private final VirtualFile myFile;
public FileCopyPresentation(String filePath, String outputFileName, ArtifactEditorContext context) {
public FileCopyPresentation(String filePath, String outputFileName) {
myOutputFileName = outputFileName;
myContext = context;
String parentPath;
myFile = LocalFileSystem.getInstance().findFileByPath(filePath);
@@ -65,7 +62,7 @@ public class FileCopyPresentation extends PackagingElementPresentation {
public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
if (myFile != null && !myFile.isDirectory()) {
presentationData.setIcons(myFile != null ? myFile.getIcon() : FileCopyElementType.ICON);
presentationData.setIcons(myFile.getIcon());
presentationData.addText(myOutputFileName, mainAttributes);
presentationData.addText(" (" + mySourcePath + ")", commentAttributes);
}
@@ -17,7 +17,6 @@
package com.intellij.compiler.ant.taskdefs;
import com.intellij.compiler.ant.Tag;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NonNls;
/**
@@ -27,8 +26,7 @@ import org.jetbrains.annotations.NonNls;
public class Include extends Tag {
public Include(@NonNls final String name) {
//noinspection HardCodedStringLiteral
super("include", new Pair[] {new Pair<String, String>("name", name)});
super("include", pair("name", name));
}
}
@@ -17,7 +17,6 @@
package com.intellij.compiler.ant.taskdefs;
import com.intellij.compiler.ant.Tag;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NonNls;
/**
@@ -26,7 +25,6 @@ import org.jetbrains.annotations.NonNls;
*/
public class PatternSet extends Tag{
public PatternSet(@NonNls final String id) {
//noinspection HardCodedStringLiteral
super("patternset", new Pair[] {new Pair<String, String>("id", id)});
super("patternset", pair("id", id));
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.ant.taskdefs;
import com.intellij.compiler.ant.Tag;
/**
* @author nik
*/
public class Unzip extends Tag {
public Unzip(String archivePath, String dest) {
super("unzip", pair("src", archivePath), pair("dest", dest));
}
}
@@ -17,9 +17,11 @@
package com.intellij.compiler.ant.taskdefs;
import com.intellij.compiler.ant.Tag;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -31,12 +33,23 @@ import java.io.File;
public class ZipFileSet extends Tag{
public static final ZipFileSet[] EMPTY_ARRAY = new ZipFileSet[0];
private ZipFileSet(@NonNls String tagName, Pair... tagOptions) {
super(tagName, tagOptions);
}
public ZipFileSet(@NonNls String fileOrDir, @NonNls final String relativePath, boolean isDir) {
super("zipfileset",
pair(isDir ? "dir" : "file", fileOrDir),
pair("prefix", prefix(isDir, relativePath)));
}
public static ZipFileSet createUnpackedSet(@NonNls String zipFilePath, @NotNull String relativePath, final boolean isDir, String pattern) {
return new ZipFileSet("zipfileset",
pair("src", zipFilePath),
pair("prefix", prefix(isDir, relativePath)),
pair("includes", pattern));
}
@Nullable
private static String prefix(final boolean isDir, final String relativePath) {
String path;
@@ -15,8 +15,8 @@
*/
package com.intellij.packaging.elements;
import com.intellij.compiler.ant.Tag;
import com.intellij.compiler.ant.Generator;
import com.intellij.compiler.ant.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,8 +32,11 @@ public interface AntCopyInstructionCreator {
Tag createFileCopyInstruction(@NotNull String filePath, String outputFileName);
@NotNull
AntCopyInstructionCreator subFolder(String directoryName);
AntCopyInstructionCreator subFolder(@NotNull String directoryName);
@Nullable
Generator createSubFolderCommand(String directoryName);
Generator createSubFolderCommand(@NotNull String directoryName);
@NotNull
Generator createExtractedDirectoryInstruction(@NotNull String jarPath, @NotNull String pathInJar);
}
@@ -67,6 +67,10 @@ public abstract class PackagingElementFactory {
@NotNull
public abstract PackagingElement<?> createDirectoryCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath);
@NotNull
public abstract PackagingElement<?> createExtractedDirectoryWithParentDirectories(@NotNull String jarPath, @NotNull String pathInJar,
@NotNull String relativeOutputPath);
@NotNull
public abstract PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath,
@Nullable String outputFileName);
@@ -22,6 +22,7 @@ public class PackagingElementWeights {
public static final int ARTIFACT = 100;
public static final int DIRECTORY = 50;
public static final int DIRECTORY_COPY = 40;
public static final int EXTRACTED_DIRECTORY = 39;
public static final int LIBRARY = 30;
public static final int MODULE = 20;
public static final int FACET = 10;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

@@ -349,7 +349,14 @@ public class CommentByBlockCommentHandler implements CodeInsightActionHandler {
else {
space = "";
}
TextRange range = insertNestedComments(chars, startOffset, endOffset, space + commentPrefix + "\n", space + commentSuffix + "\n", commenter);
final StringBuilder nestingPrefix = new StringBuilder(space).append(commentPrefix);
if (!commentPrefix.endsWith("\n")){
nestingPrefix.append("\n");
}
final StringBuilder nestingSuffix = new StringBuilder(space);
nestingSuffix.append(commentSuffix.startsWith("\n") ? commentSuffix.substring(1) : commentSuffix);
nestingSuffix.append("\n");
TextRange range = insertNestedComments(chars, startOffset, endOffset, nestingPrefix.toString(), nestingSuffix.toString(), commenter);
myEditor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
//myEditor.getSelectionModel().removeSelection();
LogicalPosition pos = new LogicalPosition(caretPosition.line + 1, caretPosition.column);
@@ -224,7 +224,8 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
}
boolean allLineCommented = true;
boolean commentWithIndent = CodeStyleSettingsManager.getSettings(myProject).LINE_COMMENT_AT_FIRST_COLUMN;
for (int line = myStartLine; line <= myEndLine; line++) {
Commenter commenter = blockSuitableCommenter != null ? blockSuitableCommenter : findCommenter(line);
if (commenter == null) return;
@@ -245,12 +246,18 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler {
myCommenters[line - myStartLine] = commenter;
if (!isLineCommented(line, chars, commenter) && (singleline || !isLineEmpty(line))) {
allLineCommented = false;
if (commenter instanceof IndentedCommenter){
final Boolean value = ((IndentedCommenter)commenter).forceIndentedLineComment();
if (value != null){
commentWithIndent = value;
}
}
break;
}
}
if (!allLineCommented) {
if (CodeStyleSettingsManager.getSettings(myProject).LINE_COMMENT_AT_FIRST_COLUMN) {
if (!commentWithIndent) {
doDefaultCommenting(blockSuitableCommenter);
}
else {
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.generation;
import com.intellij.lang.Commenter;
import org.jetbrains.annotations.Nullable;
/**
* @author oleg
*/
public interface IndentedCommenter extends Commenter {
/**
* Used to override CodeStyleSetings#LINE_COMMENT_AT_FIRST_COLUMN option
* @return true or false to overrride, null to use settings option
*/
@Nullable
Boolean forceIndentedLineComment();
}
@@ -195,7 +195,7 @@ public class EditorWindow implements EditorEx, UserDataHolderEx {
}
@NotNull
public FoldingModel getFoldingModel() {
public FoldingModelEx getFoldingModel() {
return myFoldingModelWindow;
}
@@ -283,6 +283,11 @@ public class EditorWindow implements EditorEx, UserDataHolderEx {
@NotNull
public LogicalPosition offsetToLogicalPosition(final int offset) {
return offsetToLogicalPosition(offset, true);
}
@NotNull
public LogicalPosition offsetToLogicalPosition(final int offset, boolean softWrapAware) {
assert isValid();
int lineNumber = myDocumentWindow.getLineNumber(offset);
int lineStartOffset = myDocumentWindow.getLineStartOffset(lineNumber);
@@ -465,6 +470,11 @@ public class EditorWindow implements EditorEx, UserDataHolderEx {
@NotNull
public LogicalPosition visualToLogicalPosition(@NotNull final VisualPosition pos) {
return visualToLogicalPosition(pos, true);
}
@NotNull
public LogicalPosition visualToLogicalPosition(@NotNull final VisualPosition pos, boolean softWrapAware) {
assert isValid();
return new LogicalPosition(pos.line, pos.column);
}
@@ -112,7 +112,7 @@ public class TogglePopupHintsPanel implements StatusBarWidget, StatusBarWidget.I
return "InspectionProfile";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -38,6 +38,7 @@ import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -70,6 +70,10 @@ public interface StatusBar extends StatusBarInfo {
@Deprecated
void addCustomIndicationComponent(@NotNull JComponent c);
/**
* @deprecated use removeWidget instead
*/
@Deprecated
void removeCustomIndicationComponent(@NotNull JComponent c);
void removeWidget(@NotNull String id);
@@ -33,7 +33,7 @@ import java.awt.event.MouseEvent;
*/
public interface StatusBarWidget extends Disposable {
enum Type {
enum PlatformType {
DEFAULT, MAC
}
@@ -75,7 +75,7 @@ public interface StatusBarWidget extends Disposable {
String ID();
@Nullable
WidgetPresentation getPresentation(@NotNull Type type);
WidgetPresentation getPresentation(@NotNull PlatformType type);
void install(@NotNull final StatusBar statusBar);
@@ -74,7 +74,7 @@ public class IdeMessagePanel extends JPanel implements MessagePoolListener, Cust
return "FatalError";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -50,7 +50,7 @@ public class IdeNotificationArea implements StatusBarWidget, StatusBarWidget.Ico
public IdeNotificationArea() {
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -21,6 +21,9 @@ import com.intellij.ide.DeleteProvider;
import com.intellij.ide.PasteProvider;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.impl.TextDrawingCallback;
@@ -124,4 +127,13 @@ public interface EditorEx extends Editor {
int calcColumnNumber(int offset, int lineIndex);
TextDrawingCallback getTextDrawingCallback();
@NotNull
@Override
FoldingModelEx getFoldingModel();
@NotNull
LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visiblePos, boolean softWrapAware);
@NotNull LogicalPosition offsetToLogicalPosition(int offset, boolean softWrapAware);
}
@@ -35,26 +35,22 @@ import java.util.List;
public interface SoftWrapModelEx extends SoftWrapModel {
/**
* Asks current model to adjust logical position for the given visual position if necessary.
* <p/>
* Given logical position is allowed to be non-soft wrap aware, i.e. the one calculated as there are no soft wraps at the moment.
* Asks current model to map given visual position to logical.
*
* @param defaultLogical default logical position that corresponds to the given visual position
* @param visual target visual position for which logical position should be adjusted if necessary
* @param visual target visual position for which logical position should be mapped
* @return logical position that corresponds to the given visual position
*/
@NotNull
LogicalPosition adjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual);
LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual);
/**
* Asks current model to adjust logical position for the given document offset.
* Asks current model to map given document offset to logical position.
*
* @param defaultLogical default logical position that corresponds to the given document offset
* @param offset target editor document offset
* @return logical position for the given editor document offset
*/
@NotNull
LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset);
LogicalPosition offsetToLogicalPosition(int offset);
/**
* Asks current model to adjust visual position that corresponds to the given logical position if necessary.
@@ -103,7 +99,15 @@ public interface SoftWrapModelEx extends SoftWrapModel {
* @param drawingType target drawing type
* @return width in pixels required for the painting of the given type
*/
int getMinDrawingWidth(@NotNull SoftWrapDrawingType drawingType);
int getMinDrawingWidthInPixels(@NotNull SoftWrapDrawingType drawingType);
/**
* Allows to ask for the minimal width in columns required for painting of the given type.
*
* @param drawingType target drawing type
* @return width in columns required for the painting of the given type
*/
int getMinDrawingWidthInColumns(@NotNull SoftWrapDrawingType drawingType);
/**
* Registers given listener within the current model
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class EditorUtil {
private EditorUtil() { }
@@ -178,54 +179,69 @@ public class EditorUtil {
*/
public static int calcOffset(Editor editor, CharSequence text, int start, int end, int columnNumber, int tabSize) {
final int maxScanIndex = Math.min(start + columnNumber + 1, end);
if (editor == null) {
return calcSoftWrapUnawareOffset(text, start, maxScanIndex, columnNumber, tabSize);
}
EditorEx editorImpl = (EditorEx)editor;
int offset = start;
IterationState state = new IterationState(editorImpl, offset, false);
int fontType = state.getMergedAttributes().getFontType();
int column = 0;
int x = 0;
int spaceSize = getSpaceWidth(fontType, editorImpl);
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
while (column < columnNumber) {
TextChange softWrap = softWrapModel.getSoftWrap(offset);
if (softWrap != null) {
x = softWrapModel.getSoftWrapIndentWidthInPixels(softWrap);
List<? extends TextChange> softWraps = softWrapModel.getSoftWrapsForRange(start, maxScanIndex);
int startToUse = start;
int x = 0;
AtomicInteger currentColumn = new AtomicInteger();
for (TextChange softWrap : softWraps) {
// There is a possible case that target column points inside soft wrap-introduced virtual space.
if (currentColumn.get() >= columnNumber) {
return startToUse;
}
if (offset >= state.getEndOffset()) {
state.advance();
fontType = state.getMergedAttributes().getFontType();
int result = calcSoftWrapUnawareOffset(editor, text, startToUse, softWrap.getEnd(), columnNumber, tabSize, x, currentColumn);
if (result >= 0) {
return result;
}
char c = offset < end ? text.charAt(offset++) : ' ';
int prevX = x;
if (c == '\t') {
x = nextTabStop(x, editorImpl);
}
else {
x += charWidth(c, fontType, editorImpl);
}
column += columnsNumber(c, x, prevX, spaceSize);
startToUse = softWrap.getStart();
x = softWrapModel.getSoftWrapIndentWidthInPixels(softWrap);
}
//if (column == columnNumber && offset < end && text.charAt(offset) == '\t' && (nextTabStop(x, editorImpl) - x) / spaceSize == 0) {
// offset++;
//}
if (column > columnNumber) offset--;
return offset;
// There is a possible case that target column points inside soft wrap-introduced virtual space.
if (currentColumn.get() >= columnNumber) {
return startToUse;
}
int result = calcSoftWrapUnawareOffset(editor, text, startToUse, end, columnNumber, tabSize, x, currentColumn);
if (result >= 0) {
return result;
}
// We assume that given column points to the virtual space after the line end if control flow reaches this place,
// hence, just return end of line offset then.
return end;
}
private static int calcSoftWrapUnawareOffset(CharSequence text, int start, int end, int columnNumber, int tabSize) {
/**
* Tries to match given logical column to the document offset assuming that it's located at <code>[start; end)</code> region.
*
* @param editor editor that is used to represent target document
* @param text target document text
* @param start start offset to check (inclusive)
* @param end end offset to check (exclusive)
* @param columnNumber target logical column number
* @param tabSize user-defined desired number of columns to use for tabulation symbol representation
* @param x <code>'x'</code> coordinate that corresponds to the given <code>'start'</code> offset
* @param currentColumn logical column that corresponds to the given <code>'start'</code> offset
* @return target offset that belongs to the <code>[start; end)</code> range and points to the target logical
* column if any; <code>-1</code> otherwise
*/
private static int calcSoftWrapUnawareOffset(Editor editor, CharSequence text, int start, int end, int columnNumber, int tabSize, int x,
AtomicInteger currentColumn)
{
// The main problem in a calculation is that target text may contain tabulation symbols and every such symbol may take different
// number of logical columns to represent. E.g. it takes two columns if tab size is four and current column is two; three columns
// if tab size is four and current column is one etc. So, first of all we check if there are tabulation symbols at the target
// text fragment.
boolean useOptimization = true;
boolean hasNonTabs = false;
boolean hasTabs = false;
for (int i = start; i < end; i++) {
if (text.charAt(i) == '\t') {
hasTabs = true;
if (hasNonTabs) {
useOptimization = false;
break;
}
} else {
@@ -233,20 +249,77 @@ public class EditorUtil {
}
}
if (!hasTabs) return Math.min(start + columnNumber, end);
// Perform optimized processing if possible. 'Optimized' here means the processing when we exactly know how many logical
// columns are occupied by tabulation symbols.
if (editor == null || useOptimization) {
if (!hasTabs) {
int result = start + columnNumber - currentColumn.get();
if (result < end) {
return result;
}
else {
currentColumn.addAndGet(end - start);
return -1;
}
}
int shift = 0;
int offset = start;
for (; offset < end && offset + shift < start + columnNumber; offset++) {
if (text.charAt(offset) == '\t') {
shift += getTabLength(offset + shift - start, tabSize) - 1;
int shift = 0;
int offset = start;
int prevX = x;
for (; offset < end && offset + shift + currentColumn.get() < start + columnNumber; offset++) {
if (text.charAt(offset) == '\t') {
int nextX = nextTabStop(prevX, editor, tabSize);
shift += columnsNumber(nextX - prevX, getSpaceWidth(Font.PLAIN, editor));
prevX = nextX;
}
}
int diff = start + columnNumber - offset - shift - currentColumn.get();
if (diff < 0) {
return offset - 1;
}
else if (diff == 0) {
return offset;
}
else {
currentColumn.addAndGet(offset - start + shift);
return -1;
}
}
if (offset + shift > start + columnNumber) {
offset--;
// It means that there are tabulation symbols that can't be explicitly mapped to the occupied logical columns number,
// hence, we need to perform special calculations to get know that.
EditorEx editorImpl = (EditorEx)editor;
int offset = start;
IterationState state = new IterationState(editorImpl, offset, false);
int fontType = state.getMergedAttributes().getFontType();
int column = currentColumn.get();
int spaceSize = getSpaceWidth(fontType, editorImpl);
for (; column <= columnNumber && offset < end; offset++) {
if (offset >= state.getEndOffset()) {
state.advance();
fontType = state.getMergedAttributes().getFontType();
}
char c = text.charAt(offset);
if (c == '\t') {
int prevX = x;
x = nextTabStop(x, editorImpl);
column += columnsNumber(x - prevX, spaceSize);
}
else {
x += charWidth(c, fontType, editorImpl);
column++;
}
}
return offset;
if (column == columnNumber) {
return offset;
}
if (column > columnNumber && text.charAt(offset) == '\t') {
return offset - 1;
}
currentColumn.set(column);
return -1;
}
private static int getTabLength(int colNumber, int tabSize) {
@@ -328,7 +401,10 @@ public class EditorUtil {
if (tabSize <= 0) {
tabSize = 1;
}
return nextTabStop(x, editor, tabSize);
}
public static int nextTabStop(int x, Editor editor, int tabSize) {
tabSize *= getSpaceWidth(Font.PLAIN, editor);
int nTabs = x / tabSize;
@@ -371,6 +447,21 @@ public class EditorUtil {
return result;
}
/**
* Allows to answer how many visual columns are occupied by the given width.
*
* @param width target width
* @param spaceSize width of the single space symbol within the target editor
* @return number of visual columns are occupied by the given width
*/
public static int columnsNumber(int width, int spaceSize) {
int result = width / spaceSize;
if (width % spaceSize > 0) {
result++;
}
return result;
}
/**
* Allows to answer what width in pixels is required to draw fragment of the given char array from <code>[start; end)</code> interval
* at the given editor.
@@ -390,10 +481,10 @@ public class EditorUtil {
* from <code>[1; tab size]</code> (check {@link #nextTabStop(int, Editor)} for more details)
* @return width in pixels required for target text representation
*/
public static int textWidth(@NotNull Editor editor, char[] text, int start, int end, int fontType, int x) {
public static int textWidth(@NotNull Editor editor, CharSequence text, int start, int end, int fontType, int x) {
int result = 0;
for (int i = start; i < end; i++) {
char c = text[i];
char c = text.charAt(i);
if (c != '\t') {
FontInfo font = fontForChar(c, fontType, editor);
result += font.charWidth(c, editor.getContentComponent());
@@ -470,24 +470,27 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
private VerticalInfo createVerticalInfo(LogicalPosition position) {
Document document = myEditor.getDocument();
int line = position.line;
int logicalLine = position.line;
// There is a possible case that active logical line is represented on multiple lines due to soft wraps processing.
// We want to highlight those visual lines as 'active' then, so, we calculate 'y' position for the logical line start
// and height in accordance with the number of occupied visual lines.
int y = myEditor.logicalPositionToXY(myEditor.offsetToLogicalPosition(document.getLineStartOffset(line))).y;
LogicalPosition logicalPosition = myEditor.offsetToLogicalPosition(document.getLineStartOffset(logicalLine));
VisualPosition visualPosition = myEditor.logicalToVisualPosition(logicalPosition);
int y = myEditor.visualPositionToXY(visualPosition).y;
int height = myEditor.getLineHeight();
if (line < document.getLineCount() - 1) {
int nextLineY = myEditor.logicalPositionToXY(myEditor.offsetToLogicalPosition(document.getLineStartOffset(line + 1))).y;
int heightCandidate = nextLineY - y;
// There is a possible case that active line is the one that ends with folding, so, 'y' position
// of its next logical line is the same as the previous. We explicitly check that in order to use non-standard
// line height only in case of visible soft-wrapped line.
if (heightCandidate > height) {
height = heightCandidate;
int visualLine = visualPosition.line + 1;
while (true) {
LogicalPosition logical = myEditor.visualToLogicalPosition(new VisualPosition(visualLine, 0));
if (logical.line == logicalLine) {
height += myEditor.getLineHeight();
visualLine++;
}
else {
break;
}
}
return new VerticalInfo(y, height);
}
@@ -17,6 +17,9 @@ package com.intellij.openapi.editor.impl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
/**
* @author Denis Zhdanov
@@ -31,17 +34,17 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen
}
@Override
public int toVisualColumnSymbolsNumber(CharSequence text, int start, int end, int x) {
public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) {
return EditorUtil.textWidthInColumns(myEditor, text, start, end, x);
}
@Override
public int charWidth(char c, int x, int fontType) {
if (c == '\t') {
return EditorUtil.nextTabStop(x, myEditor) - x;
}
else {
return EditorUtil.charWidth(c, fontType, myEditor);
}
public int toVisualColumnSymbolsNumber(int width) {
return EditorUtil.columnsNumber(width, EditorUtil.getSpaceWidth(Font.PLAIN, myEditor));
}
@Override
public int textWidth(@NotNull CharSequence text, int start, int end, int x) {
return EditorUtil.textWidth(myEditor, text, start, end, Font.PLAIN, x);
}
}
@@ -440,7 +440,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
@NotNull
public FoldingModel getFoldingModel() {
public FoldingModelEx getFoldingModel() {
return myFoldingModel;
}
@@ -902,7 +902,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// Process 'after soft wrap' sign.
prevX = x;
charWidth = mySoftWrapModel.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
charWidth = mySoftWrapModel.getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
x += charWidth;
if (x >= px) {
break outer;
@@ -983,16 +983,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return offsetToLogicalPosition(offset, true);
}
@NotNull
@Override
public LogicalPosition offsetToLogicalPosition(int offset, boolean softWrapAware) {
if (softWrapAware) {
return mySoftWrapModel.offsetToLogicalPosition(offset);
}
int line = calcLogicalLineNumber(offset, false);
int column = calcColumnNumber(offset, line, false);
LogicalPosition position = new LogicalPosition(line, column);
if (softWrapAware) {
return mySoftWrapModel.adjustLogicalPosition(position, offset);
}
else {
return position;
}
return new LogicalPosition(line, column);
}
@NotNull
@@ -1055,7 +1054,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (i >= 0) {
start = i + 1;
}
return new Point(EditorUtil.textWidth(this, softWrapChars, start, column + 1, Font.PLAIN, 0), y);
return new Point(EditorUtil.textWidth(this, softWrap.getText(), start, column + 1, Font.PLAIN, 0), y);
}
break;
}
@@ -1319,6 +1318,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
void paint(Graphics g) {
//TODO den remove
System.out.printf("EditorImpl.paint(): (%d; %d) - [%d; %d]%n", g.getClipBounds().x, g.getClipBounds().y, g.getClipBounds().width, g.getClipBounds().height);
startOptimizedScrolling();
if (myCursorUpdater != null) {
@@ -2667,10 +2668,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@NotNull
public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visiblePos) {
assertReadAccess();
if (!myFoldingModel.isFoldingEnabled() && !mySoftWrapModel.isSoftWrappingEnabled()) {
return new LogicalPosition(visiblePos.line, visiblePos.column);
return visualToLogicalPosition(visiblePos, true);
}
@NotNull
public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visiblePos, boolean softWrapAware) {
if (softWrapAware) {
return mySoftWrapModel.visualToLogicalPosition(visiblePos);
}
assertReadAccess();
if (!myFoldingModel.isFoldingEnabled()) return new LogicalPosition(visiblePos.line, visiblePos.column);
int line = visiblePos.line;
int column = visiblePos.column;
@@ -2678,35 +2685,23 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
FoldRegion lastCollapsedBefore = getLastCollapsedBeforePosition(visiblePos);
if (lastCollapsedBefore != null) {
LogicalPosition softWrapAwareLogFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset());
VisualPosition softWrapAwareVisFoldEnd = logicalToVisualPosition(softWrapAwareLogFoldEnd);
if (softWrapAwareVisFoldEnd.line == visiblePos.line) {
if (visiblePos.column == softWrapAwareVisFoldEnd.column) {
return softWrapAwareLogFoldEnd;
}
else if (visiblePos.column > softWrapAwareVisFoldEnd.column) {
int columnToUse = softWrapAwareLogFoldEnd.column + visiblePos.column - softWrapAwareVisFoldEnd.column;
return new LogicalPosition(
softWrapAwareLogFoldEnd.line, columnToUse, softWrapAwareLogFoldEnd.softWrapLinesBeforeCurrentLogicalLine,
softWrapAwareLogFoldEnd.softWrapLinesOnCurrentLogicalLine, visiblePos.column - columnToUse - softWrapAwareLogFoldEnd.foldingColumnDiff,
softWrapAwareLogFoldEnd.foldedLines, softWrapAwareLogFoldEnd.foldingColumnDiff
);
LogicalPosition logFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset(), false);
VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd, false);
line = logFoldEnd.line + (visiblePos.line - visFoldEnd.line);
if (visFoldEnd.line == visiblePos.line) {
if (visiblePos.column >= visFoldEnd.column) {
column = logFoldEnd.column + (visiblePos.column - visFoldEnd.column);
}
else {
return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset());
return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset(), false);
}
}
LogicalPosition softWrapUnawareLogFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset(), false);
VisualPosition softWrapUnawareVisFoldEnd = logicalToVisualPosition(softWrapUnawareLogFoldEnd, false);
line = softWrapUnawareLogFoldEnd.line + (visiblePos.line - softWrapUnawareVisFoldEnd.line);
}
if (column < 0) column = 0;
line = Math.min(line, myDocument.getLineCount() - 1);
LogicalPosition softWrapUnawareResult = new LogicalPosition(line, column);
return mySoftWrapModel.adjustLogicalPosition(softWrapUnawareResult, visiblePos);
return new LogicalPosition(line, column);
}
private int calcLogicalLineNumber(int offset) {
@@ -4844,7 +4839,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
TextChange softWrap = getSoftWrapModel().getSoftWrap(i);
if (softWrap != null) {
column++; // For 'after soft wrap' drawing.
x = getSoftWrapModel().getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
x = getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
}
char c = text.charAt(i);
@@ -15,6 +15,8 @@
*/
package com.intellij.openapi.editor.impl;
import org.jetbrains.annotations.NotNull;
/**
* Strategy interface for various utility methods used for representing document text at the editor.
* <p/>
@@ -37,16 +39,28 @@ public interface EditorTextRepresentationHelper {
* @param x <code>'x'</code> offset from the visual line start
* @return number of visual columns necessary for the target text sub-sequence representation
*/
int toVisualColumnSymbolsNumber(CharSequence text, int start, int end, int x);
int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x);
/**
* Allows to retrieve width (in pixels) necessary to represent given symbol at the given <code>'x'</code> offset from
* visual line start using given font type.
* Allows to answer how many visual columns is necessary for representing text of the given width.
*
* @param c target symbol which width should be calculated
* @param x current <code>'x'</code> of the visual line start to use for the target symbol representation
* @param fontType font type to use for representing given symbol
* @return number of pixels necessary for the given symbol representation
* @param width target width
* @return number of visual columns necessary for representation of the text with the given width
*/
int charWidth(char c, int x, int fontType);
int toVisualColumnSymbolsNumber(int width);
/**
* Allows to retrieve width (in pixels) necessary to represent given region (<code>[start; end)</code>) starting
* at the given <code>'x'</code> offset from visual line start using given font type.
* <p/>
* <b>Note:</b> target region is allows to contain line feeds, the width is calculated as a difference between <code>'x'</code>
* coordinates of the last and first symbols.
*
* @param text target text holder
* @param start start offset of the target text sub-sequence (inclusive)
* @param end end offset of the target text sub-sequence (exclusive)
* @param x <code>'x'</code> offset from the visual line start
* @return width in pixels necessary for the target text sub-sequence representation
*/
int textWidth(@NotNull CharSequence text, int start, int end, int x);
}
@@ -43,7 +43,7 @@ import java.util.List;
*/
public class SoftWrapModelImpl implements SoftWrapModelEx {
private final SoftWrapDataMapper myDataAdjuster;
private final SoftWrapDataMapper myDataMapper;
private final SoftWrapsStorage myStorage;
private final SoftWrapPainter myPainter;
private final SoftWrapApplianceManager myApplianceManager;
@@ -60,20 +60,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
public SoftWrapModelImpl(@NotNull final EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter) {
this(
editor, storage, painter, new DefaultSoftWrapApplianceManager(storage, editor, painter),
new SoftWrapDataMapper(editor, storage, painter, new DefaultEditorTextRepresentationHelper(editor)),
new SoftWrapDataMapper(editor, storage, new DefaultEditorTextRepresentationHelper(editor)),
new SoftWrapDocumentChangeManager(editor, storage)
);
}
public SoftWrapModelImpl(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter,
@NotNull SoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataAdjuster,
@NotNull SoftWrapApplianceManager applianceManager, @NotNull SoftWrapDataMapper dataMapper,
@NotNull SoftWrapDocumentChangeManager documentChangeManager)
{
myEditor = editor;
myStorage = storage;
myPainter = painter;
myApplianceManager = applianceManager;
myDataAdjuster = dataAdjuster;
myDataMapper = dataMapper;
myDocumentChangeManager = documentChangeManager;
}
@@ -184,25 +184,39 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
}
@Override
public int getMinDrawingWidth(@NotNull SoftWrapDrawingType drawingType) {
public int getMinDrawingWidthInPixels(@NotNull SoftWrapDrawingType drawingType) {
return myPainter.getMinDrawingWidth(drawingType);
}
@Override
public int getMinDrawingWidthInColumns(@NotNull SoftWrapDrawingType drawingType) {
return myPainter.getMinDrawingWidth(drawingType) > 0 ? 1 : 0;
}
@NotNull
public LogicalPosition adjustLogicalPosition(@NotNull LogicalPosition defaultLogical, @NotNull VisualPosition visual) {
@Override
public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) {
if (myActive > 0 || !isSoftWrappingEnabled() || myStorage.isEmpty() || myEditor.getDocument().getTextLength() <= 0) {
return defaultLogical;
return myEditor.visualToLogicalPosition(visual, false);
}
if (defaultLogical.visualPositionAware) {
return defaultLogical;
}
myActive++;
try {
return myDataAdjuster.adjustLogicalPosition(defaultLogical, visual);
return myDataMapper.visualToLogical(visual);
} finally {
myActive--;
}
finally {
}
@NotNull
@Override
public LogicalPosition offsetToLogicalPosition(int offset) {
if (myActive > 0 || !isSoftWrappingEnabled() || myStorage.isEmpty() || myEditor.getDocument().getTextLength() <= 0) {
return myEditor.offsetToLogicalPosition(offset, false);
}
myActive++;
try {
return myDataMapper.offsetToLogicalPosition(offset);
} finally {
myActive--;
}
}
@@ -215,7 +229,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
myActive++;
try {
return myDataAdjuster.offsetToLogicalPosition(offset);
return myDataMapper.offsetToLogicalPosition(offset);
} finally {
myActive--;
}
@@ -229,7 +243,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
myActive++;
try {
return myDataAdjuster.adjustVisualPosition(logical, defaultVisual);
return myDataMapper.adjustVisualPosition(logical, defaultVisual);
}
finally {
myActive--;
@@ -292,7 +306,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
}
if (start < end) {
result += EditorUtil.textWidth(myEditor, chars, start, end, Font.PLAIN, 0);
result += EditorUtil.textWidth(myEditor, softWrap.getText(), start, end, Font.PLAIN, 0);
}
return result;
@@ -29,6 +29,8 @@ import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import java.nio.CharBuffer;
/**
* Default {@link SoftWrapApplianceManager} implementation that is built with the following design guide lines:
* <pre>
@@ -214,7 +216,7 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
int x = myPainter.getMinDrawingWidth(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED);
int prevSoftWrapOffset = start;
for (int i = start; i < end; i++) {
int symbolWidth = EditorUtil.textWidth(myEditor, text, i, i + 1, fontType, x);
int symbolWidth = EditorUtil.textWidth(myEditor, CharBuffer.wrap(text), i, i + 1, fontType, x);
if (x + symbolWidth >= myVisibleAreaWidth) {
int offset = calculateSoftWrapOffset(text, i - 1, prevSoftWrapOffset, end);
if (offset >= end || offset <= prevSoftWrapOffset) {
@@ -239,7 +239,7 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
return c.getClass().getSimpleName();
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -64,7 +64,7 @@ public class EncodingPanel implements StatusBarWidget, StatusBarWidget.MultipleT
return "Encoding";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.wm.impl.status;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.TaskInfo;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.BalloonHandler;
@@ -42,15 +43,15 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
* User: spLeaner
*/
public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.status.IdeStatusBarImpl");
private InfoAndProgressPanel myInfoAndProgressPanel;
private enum Position {LEFT, RIGHT, CENTER}
@@ -93,7 +94,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
public void addWidget(@NotNull final StatusBarWidget widget) {
addWidget(widget, Position.RIGHT, "before Notifications");
addWidget(widget, Position.RIGHT, "__AUTODETECT__");
}
public void addWidget(@NotNull final StatusBarWidget widget, @NotNull String anchor) {
@@ -139,7 +140,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
@Nullable
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -158,19 +159,23 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
public void removeCustomIndicationComponent(@NotNull final JComponent c) {
for (final String key : myWidgetMap.keySet()) {
final WidgetBean bean = myWidgetMap.get(key);
if (bean.component instanceof CustomStatusBarWidget && ((CustomStatusBarWidget)bean.component).getComponent() == c) {
final Set<String> keySet = myWidgetMap.keySet();
final String[] keys = keySet.toArray(new String[keySet.size()]);
for (final String key : keys) {
final WidgetBean value = myWidgetMap.get(key);
if (value.widget instanceof CustomStatusBarWidget && value.component == c) {
removeWidget(key);
myCustomComponentIds.remove(key);
}
}
}
public void dispose() {
for (final String key : myWidgetMap.keySet()) {
final WidgetBean bean = myWidgetMap.get(key);
for (final WidgetBean bean : myWidgetMap.values()) {
Disposer.dispose(bean.widget);
}
myWidgetMap.clear();
}
private void addWidget(@NotNull final StatusBarWidget widget, @NotNull final Position pos, @NotNull String anchor) {
@@ -207,20 +212,29 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
final JComponent c = widget instanceof CustomStatusBarWidget ? ((CustomStatusBarWidget)widget).getComponent() : wrap(widget);
if (Position.RIGHT == pos && panel.getComponentCount() > 0) {
final List<String> parts = StringUtil.split(anchor, " ");
if (parts.size() < 2) {
throw new IllegalArgumentException(
"anchor should be a relative position ('before' or 'after') and widget ID, like 'after Encoding'");
String wid;
boolean before;
if (!anchor.equals("__AUTODETECT__")) {
final List<String> parts = StringUtil.split(anchor, " ");
if (parts.size() < 2 || !myWidgetMap.keySet().contains(parts.get(1))) {
wid = "Notifications";
before = true;
} else {
wid = parts.get(1);
before = "before".equalsIgnoreCase(parts.get(0));
}
} else {
wid = "Notifications";
before = true;
}
for (final String id : myWidgetMap.keySet()) {
if (id.equalsIgnoreCase(parts.get(1))) {
if (id.equalsIgnoreCase(wid)) {
final WidgetBean bean = myWidgetMap.get(id);
int i = 0;
for (final Component component : myRightPanel.getComponents()) {
if (component == bean.component) {
final String _relative = parts.get(0);
if ("before".equalsIgnoreCase(_relative)) {
if (before) {
panel.add(c, i);
updateBorder(i);
}
@@ -238,8 +252,6 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
}
}
}
throw new IllegalArgumentException("unable to find widget with id: " + parts.get(1));
}
if (Position.LEFT == pos && panel.getComponentCount() == 0) {
@@ -323,7 +335,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
private static JComponent wrap(@NotNull final StatusBarWidget widget) {
final StatusBarWidget.WidgetPresentation presentation =
widget.getPresentation(SystemInfo.isMac ? StatusBarWidget.Type.MAC : StatusBarWidget.Type.DEFAULT);
widget.getPresentation(SystemInfo.isMac ? StatusBarWidget.PlatformType.MAC : StatusBarWidget.PlatformType.DEFAULT);
assert presentation != null : "Presentation should not be null!";
JComponent wrapper;
@@ -18,15 +18,12 @@ package com.intellij.openapi.wm.impl.status;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.progress.TaskInfo;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonHandler;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.CustomStatusBarWidget;
@@ -52,9 +49,7 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidget {
private final ProcessPopup myPopup;
@@ -142,7 +137,7 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge
return "InfoAndProgress";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -42,7 +42,7 @@ public class InsertOverwritePanel implements StatusBarWidget, StatusBarWidget.Te
return "InsertOverwrite";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -70,7 +70,7 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
}
@Nullable
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -61,7 +61,7 @@ public class PositionPanel implements StatusBarWidget, StatusBarWidget.TextPrese
return "Position";
}
public WidgetPresentation getPresentation(@NotNull final Type type) {
public WidgetPresentation getPresentation(@NotNull final PlatformType type) {
return this;
}
@@ -54,7 +54,7 @@ public class ToggleReadOnlyAttributePanel implements StatusBarWidget, StatusBarW
return "ReadOnlyAttribute";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -3,10 +3,13 @@ package com.intellij.openapi.editor.impl.softwrap;
import com.intellij.mock.MockFoldRegion;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.editor.ex.SoftWrapModelEx;
import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jmock.Expectations;
import org.jmock.Mockery;
@@ -18,7 +21,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -88,7 +90,8 @@ public class SoftWrapDataMapperTest {
private EditorEx myEditor;
private Document myDocument;
private SoftWrapsStorage myStorage;
private FoldingModel myFoldingModel;
private SoftWrapModelEx mySoftWrapModel;
private FoldingModelEx myFoldingModel;
private MockEditorTextRepresentationHelper myRepresentationHelper;
@Before
@@ -100,7 +103,8 @@ public class SoftWrapDataMapperTest {
myEditor = myMockery.mock(EditorEx.class);
myDocument = myMockery.mock(Document.class);
myStorage = new SoftWrapsStorage();
myFoldingModel = myMockery.mock(FoldingModel.class);
mySoftWrapModel = myMockery.mock(SoftWrapModelEx.class);
myFoldingModel = myMockery.mock(FoldingModelEx.class);
final EditorSettings settings = myMockery.mock(EditorSettings.class);
final Project project = myMockery.mock(Project.class);
final SoftWrapPainter painter = myMockery.mock(SoftWrapPainter.class);
@@ -140,6 +144,23 @@ public class SoftWrapDataMapperTest {
allowing(settings).isWhitespacesShown();will(returnValue(true));
allowing(myEditor).getProject();will(returnValue(project));
// Soft wraps.
allowing(myEditor).getSoftWrapModel(); will(returnValue(mySoftWrapModel));
allowing(mySoftWrapModel).getSoftWrapIndentWidthInColumns(with(any(TextChange.class)));
will(new CustomAction("getSoftWrapIndentWidthInColumns") {
@Override
public Object invoke(Invocation invocation) throws Throwable {
return getSoftWrapIndentWidthInColumns((TextChange)invocation.getParameter(0));
}
});
allowing(mySoftWrapModel).getSoftWrapIndentWidthInPixels(with(any(TextChange.class)));
will(new CustomAction("getSoftWrapIndentWidthInPixels") {
@Override
public Object invoke(Invocation invocation) throws Throwable {
return getSoftWrapIndentWidthInPixels((TextChange)invocation.getParameter(0));
}
});
// Folding.
allowing(myEditor).getFoldingModel();will(returnValue(myFoldingModel));
allowing(myFoldingModel).isOffsetCollapsed(with(any(int.class))); will(new CustomAction("isOffsetCollapsed()") {
@@ -155,7 +176,7 @@ public class SoftWrapDataMapperTest {
return getCollapsedFoldRegion((Integer)invocation.getParameter(0));
}
});
allowing(myFoldingModel).getAllFoldRegions(); will(new CustomAction("getAllFoldRegions()") {
allowing(myFoldingModel).fetchTopLevel(); will(new CustomAction("fetchTopLevel()") {
@Override
public Object invoke(Invocation invocation) throws Throwable {
return myFoldRegions.toArray(new FoldRegion[myFoldRegions.size()]);
@@ -188,7 +209,7 @@ public class SoftWrapDataMapperTest {
myRepresentationHelper = new MockEditorTextRepresentationHelper();
myAdjuster = new SoftWrapDataMapper(myEditor, myStorage, painter, myRepresentationHelper, new MockFontTypeProvider());
myAdjuster = new SoftWrapDataMapper(myEditor, myStorage, myRepresentationHelper/*, new MockFontTypeProvider()*/);
}
@After
@@ -196,6 +217,16 @@ public class SoftWrapDataMapperTest {
myMockery.assertIsSatisfied();
}
@Test
public void noSoftWrapsAndFolding() {
String document =
"class Test { \n" +
" public void foo() {} \n" +
" \n" +
"}";
test(document);
}
@Test
public void softWrapHasSymbolBeforeFirstLineFeed() {
String document =
@@ -216,13 +247,13 @@ public class SoftWrapDataMapperTest {
String document =
"public class Test {\n" +
" public void foo(int[] data) {\n" +
" bar(data[0], data[1], <WRAP>\n" +
" </WRAP>data[2], data[3], <WRAP> \n" +
" </WRAP>data[4], data[5], \n" +
" data[6], data[7], \n" +
" data[8], data[9], <WRAP>\n" +
" </WRAP>data[10], data[11], <WRAP> \n" +
" </WRAP>data[12], data[13]); \n" +
" bar(data[0], <WRAP>\n" +
" </WRAP>data[1] <WRAP> \n" +
" </WRAP>data[2] \n" +
" data[3], \n" +
" data[4], <WRAP>\n" +
" </WRAP>data[5] <WRAP> \n" +
" </WRAP>data[6]); \n" +
" }\n" +
" public void bar(int ... i) {\n" +
" }\n" +
@@ -345,6 +376,34 @@ public class SoftWrapDataMapperTest {
test(document);
}
private static int getSoftWrapIndentWidthInColumns(TextChange softWrap) {
int result = 0;
CharSequence text = softWrap.getText();
for (int i = text.length() - 1; i >= 0; i--) {
if (text.charAt(i) == '\n') {
break;
}
result++;
}
if (SOFT_WRAP_DRAWING_WIDTH > 0) {
result++;
}
return result;
}
private int getSoftWrapIndentWidthInPixels(TextChange softWrap) {
int result = 0;
CharSequence text = softWrap.getText();
for (int i = text.length() - 1; i >= 0; i--) {
if (text.charAt(i) == '\n') {
break;
}
result += myRepresentationHelper.textWidth(text, i, i + 1, 0);
}
result += SOFT_WRAP_DRAWING_WIDTH;
return result;
}
private int getLineNumber(int offset) {
int line = 0;
for (TextRange range : myLineRanges) {
@@ -430,10 +489,12 @@ public class SoftWrapDataMapperTest {
for (DataEntry data : myExpectedData) {
// Check logical by visual.
LogicalPosition actualLogicalByVisual = myAdjuster.adjustLogicalPosition(toSoftWrapUnawareLogicalByVisual(data), data.visual);
LogicalPosition actualLogicalByVisual = myAdjuster.visualToLogical(data.visual);
// We don't want to perform the check for logical positions that correspond to the folded space because all of them relate to
// the same logical position of the folding start.
if (!data.foldedSpace && !data.insideTab && !equals(data.logical, actualLogicalByVisual)) {
//TODO den remove
myAdjuster.visualToLogical(data.visual);
throw new AssertionError(
String.format("Detected unmatched logical position by visual (%s). Expected: '%s', actual: '%s'. Calculation was performed "
+ "against soft wrap-unaware logical: '%s'",
@@ -446,6 +507,8 @@ public class SoftWrapDataMapperTest {
// We don't to perform the check for the data that points to soft wrap location here. The reason is that it shares offset
// with the first document symbol after soft wrap, hence, examination always fails.
if (!data.virtualSpace && !data.insideTab && !equals(data.logical, actualLogicalByOffset)) {
//TODO den remove
myAdjuster.offsetToLogicalPosition(data.offset);
throw new AssertionError(
String.format("Detected unmatched logical position by offset. Expected: '%s', actual: '%s'. Calculation was performed "
+ "against offset: '%d' and soft wrap-unaware logical: '%s'",
@@ -635,7 +698,7 @@ public class SoftWrapDataMapperTest {
}
else if (c == '\t') {
int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x);
x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
x += MockEditorTextRepresentationHelper.charWidth(c, x);
// There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor.
// We store data entry only for the first tab column without 'inside tab' flag then.
@@ -652,7 +715,7 @@ public class SoftWrapDataMapperTest {
} else {
logicalColumn++;
offset++;
x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
x += MockEditorTextRepresentationHelper.charWidth(c, x);
foldingColumnDiff--;
}
return;
@@ -685,7 +748,7 @@ public class SoftWrapDataMapperTest {
visualColumn++;
softWrapColumnDiff++;
softWrapSymbolsOnCurrentVisualLine++;
x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
x += MockEditorTextRepresentationHelper.charWidth(c, x);
}
return;
}
@@ -706,7 +769,7 @@ public class SoftWrapDataMapperTest {
}
else if (c == '\t') {
int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x);
x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
x += MockEditorTextRepresentationHelper.charWidth(c, x);
// There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor.
// We store data entry only for the first tab column without 'inside tab' flag then.
@@ -726,7 +789,7 @@ public class SoftWrapDataMapperTest {
visualColumn++;
logicalColumn++;
offset++;
x += myRepresentationHelper.charWidth(c, x, Font.PLAIN);
x += MockEditorTextRepresentationHelper.charWidth(c, x);
}
}
@@ -782,10 +845,10 @@ public class SoftWrapDataMapperTest {
}
@Override
public int toVisualColumnSymbolsNumber(CharSequence text, int start, int end, int x) {
public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) {
int result = 0;
for (int i = start; i < end; i++) {
int width = charWidth(text.charAt(i), x, Font.PLAIN);
int width = charWidth(text.charAt(i), x);
result += width / SPACE_SIZE;
if (width % SPACE_SIZE > 0) {
result++;
@@ -796,7 +859,28 @@ public class SoftWrapDataMapperTest {
}
@Override
public int charWidth(char c, int x, int fontType) {
public int toVisualColumnSymbolsNumber(int width) {
int result = width / SPACE_SIZE;
if (width % SPACE_SIZE > 0) {
result++;
}
return result;
}
@Override
public int textWidth(@NotNull CharSequence text, int start, int end, int x) {
int result = 0;
for (int i = start; i < end; i++) {
char c = text.charAt(i);
switch (c) {
case '\n': result = 0; break;
default: result += charWidth(c, result);
}
}
return result;
}
public static int charWidth(char c, int x) {
if (c == '\t') {
int tabWidth = SPACE_SIZE * TAB_SIZE;
int tabsNumber = x / tabWidth;
@@ -808,18 +892,18 @@ public class SoftWrapDataMapperTest {
}
}
private static class MockFontTypeProvider implements SoftWrapDataMapper.FontTypeProvider {
@Override
public void init(int start) {
}
@Override
public int getFontType(int offset) {
return Font.PLAIN;
}
@Override
public void cleanup() {
}
}
//private static class MockFontTypeProvider implements SoftWrapDataMapper.FontTypeProvider {
// @Override
// public void init(int start) {
// }
//
// @Override
// public int getFontType(int offset) {
// return Font.PLAIN;
// }
//
// @Override
// public void cleanup() {
// }
//}
}
@@ -79,7 +79,7 @@ status.bar.insert.status.text=Insert
status.bar.overwrite.status.text=Overwrite
popup.hints.panel.click.to.configure.highlighting.tooltip.text=Click to configure highlighting for this file
popup.hints.panel.click.to.configure.profile.text=Click to configure inspection profiles
read.only.attr.panel.double.click.to.toggle.attr.tooltip.text=Double-click to toggle the read-only attribute
read.only.attr.panel.double.click.to.toggle.attr.tooltip.text=Click to toggle the read-only attribute
welcome.screen.get.from.vcs.action.no.vcs.plugins.with.check.out.action.installed.action.name=No VCS plugins with Check-out action installed.
welcome.screen.get.from.vcs.action.checkout.from.list.popup.title=Checkout from
welcome.screen.recent.projects.action.no.recent.projects.to.display.action.name=No recent projects to display.
@@ -45,7 +45,6 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.io.URLUtil;
import org.apache.tools.ant.taskdefs.optional.junit.XMLConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.xml.sax.SAXException;
@@ -258,7 +257,7 @@ public class ExportTestResultsAction extends DumbAwareAction {
else {
Source xslSource;
if (config.getExportFormat() == ExportTestResultsConfiguration.ExportFormat.BundledTemplate) {
URL bundledXsltUrl = XMLConstants.class.getResource("/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-noframes.xsl");
URL bundledXsltUrl = getClass().getResource("junit-noframes.xsl");
xslSource = new StreamSource(URLUtil.openStream(bundledXsltUrl));
}
else {
@@ -24,7 +24,6 @@ import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.util.PairProcessor;
import org.apache.tools.ant.taskdefs.optional.junit.XMLConstants;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -34,7 +33,18 @@ import java.util.Map;
// this class generates resulting XML compatible to that of XMLJUnitResultFormatter
public class TestResultsXmlFormatter implements XMLConstants {
public class TestResultsXmlFormatter {
// see org.apache.tools.ant.taskdefs.optional.junit.XmlConstants
private static final String TESTSUITES = "testsuites";
private static final String TESTSUITE = "testsuite";
private static final String TESTCASE = "testcase";
private static final String FAILURE = "failure";
private static final String ATTR_NAME = "name";
private static final String ATTR_FAILURES = "failures";
private static final String ATTR_TESTS = "tests";
private static final Logger LOG = Logger.getInstance(TestResultsXmlFormatter.class.getName());
private final RuntimeConfiguration myRuntimeConfiguration;
@@ -0,0 +1,467 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:lxslt="http://xml.apache.org/xslt"
xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils">
<xsl:output method="html" indent="yes" encoding="US-ASCII"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
<xsl:decimal-format decimal-separator="." grouping-separator="," />
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<xsl:param name="TITLE">Unit Test Results.</xsl:param>
<!--
Sample stylesheet to be used with Ant JUnitReport output.
It creates a non-framed report that can be useful to send via
e-mail or such.
-->
<xsl:template match="testsuites">
<html>
<head>
<title><xsl:value-of select="$TITLE"/></title>
<style type="text/css">
body {
font:normal 68% verdana,arial,helvetica;
color:#000000;
}
table tr td, table tr th {
font-size: 68%;
}
table.details tr th{
font-weight: bold;
text-align:left;
background:#a6caf0;
}
table.details tr td{
background:#eeeee0;
}
p {
line-height:1.5em;
margin-top:0.5em; margin-bottom:1.0em;
}
h1 {
margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
}
h2 {
margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
}
h3 {
margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
}
h4 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
h5 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
h6 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
.Error {
font-weight:bold; color:red;
}
.Failure {
font-weight:bold; color:purple;
}
.Properties {
text-align:right;
}
</style>
<script type="text/javascript" language="JavaScript">
var TestCases = new Array();
var cur;
<xsl:for-each select="./testsuite">
<xsl:apply-templates select="properties"/>
</xsl:for-each>
</script>
<script type="text/javascript" language="JavaScript"><![CDATA[
function displayProperties (name) {
var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
var doc = win.document;
doc.open();
doc.write("<html><head><title>Properties of " + name + "</title>");
doc.write("<style>")
doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
doc.write("table tr td, table tr th { font-size: 68%; }");
doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
doc.write("</style>");
doc.write("</head><body>");
doc.write("<h3>Properties of " + name + "</h3>");
doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
doc.write("<table class='properties'>");
doc.write("<tr><th>Name</th><th>Value</th></tr>");
for (prop in TestCases[name]) {
doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
}
doc.write("</table>");
doc.write("</body></html>");
doc.close();
win.focus();
}
]]>
</script>
</head>
<body>
<a name="top"></a>
<xsl:call-template name="pageHeader"/>
<!-- Summary part -->
<xsl:call-template name="summary"/>
<hr size="1" width="95%" align="left"/>
<!-- Package List part -->
<xsl:call-template name="packagelist"/>
<hr size="1" width="95%" align="left"/>
<!-- For each package create its part -->
<xsl:call-template name="packages"/>
<hr size="1" width="95%" align="left"/>
<!-- For each class create the part -->
<xsl:call-template name="classes"/>
</body>
</html>
</xsl:template>
<!-- ================================================================== -->
<!-- Write a list of all packages with an hyperlink to the anchor of -->
<!-- of the package name. -->
<!-- ================================================================== -->
<xsl:template name="packagelist">
<h2>Packages</h2>
Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<xsl:call-template name="testsuite.test.header"/>
<!-- list all packages recursively -->
<xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
<xsl:sort select="@package"/>
<xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
<xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
<xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
<xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
<xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
<!-- write a summary for the package -->
<tr valign="top">
<!-- set a nice color depending if there is an error/failure -->
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
<xsl:when test="$errorCount &gt; 0">Error</xsl:when>
</xsl:choose>
</xsl:attribute>
<td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
<td><xsl:value-of select="$testCount"/></td>
<td><xsl:value-of select="$errorCount"/></td>
<td><xsl:value-of select="$failureCount"/></td>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="$timeCount"/>
</xsl:call-template>
</td>
<td><xsl:value-of select="$testsuites-in-package/@timestamp"/></td>
<td><xsl:value-of select="$testsuites-in-package/@hostname"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<!-- ================================================================== -->
<!-- Write a package level report -->
<!-- It creates a table with values from the document: -->
<!-- Name | Tests | Errors | Failures | Time -->
<!-- ================================================================== -->
<xsl:template name="packages">
<!-- create an anchor to this package name -->
<xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
<xsl:sort select="@package"/>
<a name="{@package}"></a>
<h3>Package <xsl:value-of select="@package"/></h3>
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<xsl:call-template name="testsuite.test.header"/>
<!-- match the testsuites of this package -->
<xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
</table>
<a href="#top">Back to top</a>
<p/>
<p/>
</xsl:for-each>
</xsl:template>
<xsl:template name="classes">
<xsl:for-each select="testsuite">
<xsl:sort select="@name"/>
<!-- create an anchor to this class name -->
<a name="{@name}"></a>
<h3>TestCase <xsl:value-of select="@name"/></h3>
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<xsl:call-template name="testcase.test.header"/>
<!--
test can even not be started at all (failure to load the class)
so report the error directly
-->
<xsl:if test="./error">
<tr class="Error">
<td colspan="4"><xsl:apply-templates select="./error"/></td>
</tr>
</xsl:if>
<xsl:apply-templates select="./testcase" mode="print.test"/>
</table>
<div class="Properties">
<a>
<xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
Properties &#187;
</a>
</div>
<p/>
<a href="#top">Back to top</a>
</xsl:for-each>
</xsl:template>
<xsl:template name="summary">
<h2>Summary</h2>
<xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
<xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
<xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
<xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
<xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
<table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
<tr valign="top">
<th>Tests</th>
<th>Failures</th>
<th>Errors</th>
<th>Success rate</th>
<th>Time</th>
</tr>
<tr valign="top">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
<xsl:when test="$errorCount &gt; 0">Error</xsl:when>
</xsl:choose>
</xsl:attribute>
<td><xsl:value-of select="$testCount"/></td>
<td><xsl:value-of select="$failureCount"/></td>
<td><xsl:value-of select="$errorCount"/></td>
<td>
<xsl:call-template name="display-percent">
<xsl:with-param name="value" select="$successRate"/>
</xsl:call-template>
</td>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="$timeCount"/>
</xsl:call-template>
</td>
</tr>
</table>
<table border="0" width="95%">
<tr>
<td style="text-align: justify;">
Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
</td>
</tr>
</table>
</xsl:template>
<!--
Write properties into a JavaScript data structure.
This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
-->
<xsl:template match="properties">
cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
<xsl:for-each select="property">
<xsl:sort select="@name"/>
cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
</xsl:for-each>
</xsl:template>
<!-- Page HEADER -->
<xsl:template name="pageHeader">
<h1><xsl:value-of select="$TITLE"/></h1>
<table width="100%">
<tr>
<td align="left"></td>
<td align="right">Designed for use with <a href='http://www.junit.org'>JUnit</a> and <a href='http://ant.apache.org/ant'>Ant</a>.</td>
</tr>
</table>
<hr size="1"/>
</xsl:template>
<xsl:template match="testsuite" mode="header">
<tr valign="top">
<th width="80%">Name</th>
<th>Tests</th>
<th>Errors</th>
<th>Failures</th>
<th nowrap="nowrap">Time(s)</th>
</tr>
</xsl:template>
<!-- class header -->
<xsl:template name="testsuite.test.header">
<tr valign="top">
<th width="80%">Name</th>
<th>Tests</th>
<th>Errors</th>
<th>Failures</th>
<th nowrap="nowrap">Time(s)</th>
<th nowrap="nowrap">Time Stamp</th>
<th>Host</th>
</tr>
</xsl:template>
<!-- method header -->
<xsl:template name="testcase.test.header">
<tr valign="top">
<th>Name</th>
<th>Status</th>
<th width="80%">Type</th>
<th nowrap="nowrap">Time(s)</th>
</tr>
</xsl:template>
<!-- class information -->
<xsl:template match="testsuite" mode="print.test">
<tr valign="top">
<!-- set a nice color depending if there is an error/failure -->
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
<xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
</xsl:choose>
</xsl:attribute>
<!-- print testsuite information -->
<td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
<td><xsl:value-of select="@tests"/></td>
<td><xsl:value-of select="@errors"/></td>
<td><xsl:value-of select="@failures"/></td>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="@time"/>
</xsl:call-template>
</td>
<td><xsl:apply-templates select="@timestamp"/></td>
<td><xsl:apply-templates select="@hostname"/></td>
</tr>
</xsl:template>
<xsl:template match="testcase" mode="print.test">
<tr valign="top">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="failure | error">Error</xsl:when>
</xsl:choose>
</xsl:attribute>
<td><xsl:value-of select="@name"/></td>
<xsl:choose>
<xsl:when test="failure">
<td>Failure</td>
<td><xsl:apply-templates select="failure"/></td>
</xsl:when>
<xsl:when test="error">
<td>Error</td>
<td><xsl:apply-templates select="error"/></td>
</xsl:when>
<xsl:otherwise>
<td>Success</td>
<td></td>
</xsl:otherwise>
</xsl:choose>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="@time"/>
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template match="failure">
<xsl:call-template name="display-failures"/>
</xsl:template>
<xsl:template match="error">
<xsl:call-template name="display-failures"/>
</xsl:template>
<!-- Style for the error and failure in the tescase template -->
<xsl:template name="display-failures">
<xsl:choose>
<xsl:when test="not(@message)">N/A</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@message"/>
</xsl:otherwise>
</xsl:choose>
<!-- display the stacktrace -->
<code>
<br/><br/>
<xsl:call-template name="br-replace">
<xsl:with-param name="word" select="."/>
</xsl:call-template>
</code>
<!-- the later is better but might be problematic for non-21" monitors... -->
<!--pre><xsl:value-of select="."/></pre-->
</xsl:template>
<xsl:template name="JS-escape">
<xsl:param name="string"/>
<xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
<xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
<xsl:value-of select="$tmp2"/>
</xsl:template>
<!--
template that will convert a carriage return into a br tag
@param word the text from which to convert CR to BR tag
-->
<xsl:template name="br-replace">
<xsl:param name="word"/>
<xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
</xsl:template>
<xsl:template name="display-time">
<xsl:param name="value"/>
<xsl:value-of select="format-number($value,'0.000')"/>
</xsl:template>
<xsl:template name="display-percent">
<xsl:param name="value"/>
<xsl:value-of select="format-number($value,'0.00%')"/>
</xsl:template>
</xsl:stylesheet>
-1
View File
@@ -11,7 +11,6 @@
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module" module-name="xdebugger-api" />
<orderEntry type="library" name="Ant" level="project" />
</component>
</module>
@@ -510,7 +510,7 @@ public class FileUtil {
return parentFile.exists() && parentFile.isDirectory() || parentFile.mkdirs();
}
}
return false;
return true;
}
public static boolean createIfDoesntExist(File file) {
@@ -1236,6 +1236,20 @@ public class StringUtil {
return i;
}
/**
* Allows to answer if target symbol is contained at given char sequence at <code>[start; end)</code> interval.
*
* @param s target char sequence to check
* @param start start offset to use within the given char sequence (inclusive)
* @param end end offset to use within the given char sequence (exclusive)
* @param c target symbol to check
* @return <code>true</code> if given symbol is contained at the target range of the given char sequence;
* <code>false</code> otherwise
*/
public static boolean contains(CharSequence s, int start, int end, char c) {
return indexOf(s, c, start, end) >= 0;
}
public static int indexOf(@NotNull CharSequence s, char c) {
return indexOf(s, c, 0, s.length());
}
@@ -163,7 +163,7 @@ public class IncomingChangesIndicator implements ProjectComponent {
return "IncomingChanges";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return this;
}
@@ -174,7 +174,7 @@ public class IOResourceInspection extends ResourceInspection {
public boolean isIOResource(PsiExpression expression){
return TypeUtils.expressionHasTypeOrSubtype(expression,
"java.io.InputStream", "java.io.Writer", "java.io.Reader",
"java.io.RandomAccessFile", "java.io.OutputStream") != null &&
"java.io.RandomAccessFile", "java.io.OutputStream", "java.util.zip.ZipFile") != null &&
!isIgnoredType(expression);
}
+14
View File
@@ -207,6 +207,11 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
* The reference tracker
*/
private GitReferenceTracker myReferenceTracker;
/**
* If true, the vcs was activated
*/
private boolean isActivated;
public static GitVcs getInstance(@NotNull Project project) {
return (GitVcs)ProjectLevelVcsManager.getInstance(project).findVcsByName(NAME);
@@ -496,6 +501,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
*/
@Override
protected void activate() {
isActivated = true;
if (!myProject.isDefault() && myRootTracker == null) {
myRootTracker = new GitRootTracker(this, myProject, myRootListeners.getMulticaster());
}
@@ -519,6 +525,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
*/
@Override
protected void deactivate() {
isActivated = false;
GitBranchConfigurations.getInstance(myProject).deactivate();
if (myRootTracker != null) {
myRootTracker.dispose();
@@ -768,4 +775,11 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
final VirtualFile vcsRoot = GitUtil.getGitRoot(file);
return GitChangeUtils.getRevisionChanges(project, vcsRoot, revision.getRevisionNumber().asString(), false);
}
/**
* @return true if vcs was activated
*/
public boolean isActivated() {
return isActivated;
}
}
@@ -256,7 +256,7 @@ public class GitPushActiveBranchesDialog extends DialogWrapper {
if (seenMerges) {
rootsWithMerges.add(r.root);
}
if (r.remoteCommits > 0 && seenCheckedNode || reorderNeeded) {
if (r.remoteCommits > 0 || reorderNeeded) {
roots.add(r.root);
}
if (reorderNeeded) {
@@ -49,6 +49,7 @@ import git4idea.vfs.GitReferenceListener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
/**
@@ -147,6 +148,10 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
* Listener for changes
*/
private final ChangeListAdapter myChangesListener;
/**
* If true, the widget is enabled
*/
private boolean myWidgetEnabled = true;
/**
* The constructor used to dependency injection
@@ -268,8 +273,20 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
}
referencesChanged();
}
if (isWidgetEnabled()) {
installWidget();
}
}
/**
* Install widget
*/
private void installWidget() {
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
myWidgetUninstall = GitBranchesWidget.install(myProject, this);
final Runnable r = GitBranchesWidget.install(myProject, this);
synchronized (myStateLock) {
myWidgetUninstall = r;
}
}
}
@@ -279,10 +296,18 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
public void deactivate() {
myVcs.removeGitReferenceListener(myReferenceListener);
myChangeManager.removeChangeListListener(myChangesListener);
if (myWidgetUninstall != null) {
myWidgetUninstall.run();
uninstallWidget();
}
private void uninstallWidget() {
final Runnable r;
synchronized (myStateLock) {
r = myWidgetUninstall;
myWidgetUninstall = null;
}
if (r != null) {
r.run();
}
}
/**
@@ -310,6 +335,7 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
public State getState() {
synchronized (myStateLock) {
State rc = new State();
rc.IS_WIDGET_ENABLED = myWidgetEnabled;
rc.CURRENT = myCurrentConfiguration == null ? null : myCurrentConfiguration.getName();
ArrayList<BranchConfiguration> cs = new ArrayList<BranchConfiguration>(myConfigurations.size());
for (GitBranchConfiguration ci : myConfigurations.values()) {
@@ -363,9 +389,54 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
}
fireCurrentConfigurationChanged();
fireConfigurationsChanged();
if (state.IS_WIDGET_ENABLED != myWidgetEnabled) {
myWidgetEnabled = state.IS_WIDGET_ENABLED;
updateWidgetState();
}
}
}
/**
* Update widget state after update
*/
private void updateWidgetState() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (isWidgetEnabled()) {
if (myVcs.isActivated() && myWidgetUninstall == null) {
installWidget();
}
}
else {
uninstallWidget();
}
}
});
}
/**
* @return true if widget is enabled
*/
public boolean isWidgetEnabled() {
synchronized (myStateLock) {
return myWidgetEnabled;
}
}
/**
* Update widget state
*
* @param value true to enable widget
*/
public void setWidgetEnabled(boolean value) {
synchronized (myStateLock) {
myWidgetEnabled = value;
updateWidgetState();
}
}
/**
* @return the candidate remote configurations
*/
@@ -632,18 +703,6 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
return myStateLock;
}
/**
* Check if configuration with specified name already exists
*
* @param name the name to check
* @return true if the configuration exists
*/
boolean hasConfigurationName(String name) {
synchronized (myStateLock) {
return myConfigurations.containsKey(name);
}
}
/**
* Set current configuration
*
@@ -765,6 +824,10 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
* The configuration state
*/
public static class State {
/**
* If true, branches widget is enabled
*/
public boolean IS_WIDGET_ENABLED = true;
/**
* The current configuration
*/
@@ -76,6 +76,10 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
* The project
*/
final Project myProject;
/**
* The status bar
*/
private final StatusBar myStatusBar;
/**
* The configurations instance
*/
@@ -88,10 +92,6 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
* The candidate remote configurations. Null if invalidated or non-initialized
*/
private AnAction[] myRemoveConfigurations;
/**
* The status bar
*/
private StatusBar myStatusBar;
/**
* If true, the popup is enabled
*/
@@ -113,12 +113,14 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
/**
* The constructor
*
* @param project the project instance
* @param project the project instance
* @param statusBar the status bar
* @param configurations the configuration settings
*/
public GitBranchesWidget(Project project, GitBranchConfigurations configurations) {
public GitBranchesWidget(Project project, StatusBar statusBar, GitBranchConfigurations configurations) {
myProject = project;
myStatusBar = statusBar;
setBorder(WidgetBorder.INSTANCE);
//setBorder(BorderFactory.createEtchedBorder());
myConfigurations = configurations;
myDefaultForeground = getForeground();
myConfigurationsListener = new MyGitBranchConfigurationsListener();
@@ -148,7 +150,7 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
public void run() {
StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
if (statusBar != null) {
final GitBranchesWidget w = new GitBranchesWidget(project, configurations);
final GitBranchesWidget w = new GitBranchesWidget(project, statusBar, configurations);
statusBar.addWidget(w, "after " + (SystemInfo.isMac ? "Encoding" : "InsertOverwrite"), project);
widget.set(w);
}
@@ -191,7 +193,7 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
* {@inheritDoc}
*/
@Override
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -200,7 +202,6 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
*/
@Override
public void install(@NotNull StatusBar statusBar) {
myStatusBar = statusBar;
}
/**
@@ -550,5 +551,4 @@ public class GitBranchesWidget extends JLabel implements CustomStatusBarWidget {
});
}
}
}
@@ -585,10 +585,7 @@ public class GitCheckoutProcess {
LocalChangeList defaultList = myChangeManager.getDefaultChangeList();
for (ChangeListInfo changeListInfo : changes.CHANGE_LISTS) {
LocalChangeList changeList = lists.get(changeListInfo.NAME);
if (changeList != null) {
myChangeManager.setReadOnly(changeList.getName(), false);
}
else {
if (changeList == null) {
changeList = myChangeManager.addChangeList(changeListInfo.NAME, changeListInfo.COMMENT);
lists.put(changeListInfo.NAME, changeList);
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="git4idea.config.GitVcsPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -10,107 +10,150 @@
</properties>
<border type="none"/>
<children>
<component id="b1a9d" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.path.label"/>
<verifyInputWhenFocusTarget value="false"/>
</properties>
</component>
<component id="25af7" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myGitField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<vspacer id="4c83d">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="563b2" class="javax.swing.JButton" binding="myTestButton">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="2" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<horizontalAlignment value="0"/>
<label resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.test.label"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.test"/>
</properties>
</component>
<component id="5a909" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="f5de9"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.ssh.mode"/>
</properties>
</component>
<grid id="97c7d" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="b95e2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<border type="etched" title="Interface Options">
<font/>
</border>
<children>
<component id="f5de9" class="javax.swing.JComboBox" binding="mySSHExecutableComboBox" default-binding="true">
<component id="26b57" class="javax.swing.JCheckBox" binding="myEnableBranchesWidgetCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="Enable &amp;branches widget"/>
<toolTipText value="Enables status widget in status bar"/>
</properties>
</component>
<hspacer id="9eafb">
<hspacer id="a6134">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<component id="a6d8e" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="7a626"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.crlf"/>
</properties>
</component>
<grid id="a4472" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="e7668" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<border type="etched" title="File Conversion"/>
<children>
<component id="a6d8e" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="7a626"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.crlf"/>
</properties>
</component>
<hspacer id="9e883">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="8bedb">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="7a626" class="javax.swing.JComboBox" binding="myConvertTextFilesComboBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<toolTipText resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.tooltip"/>
</properties>
</component>
<hspacer id="3c6b8">
<component id="a8818" class="javax.swing.JCheckBox" binding="myAskBeforeConversionsCheckBox" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<properties>
<selected value="true"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.ask"/>
<toolTipText resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.ask.tooltip"/>
</properties>
</component>
</children>
</grid>
<component id="a8818" class="javax.swing.JCheckBox" binding="myAskBeforeConversionsCheckBox" default-binding="true">
<grid id="c9e6b" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.ask"/>
<toolTipText resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.convert.ask.tooltip"/>
</properties>
</component>
<properties/>
<border type="etched" title="Git"/>
<children>
<component id="b1a9d" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.path.label"/>
<verifyInputWhenFocusTarget value="false"/>
</properties>
</component>
<component id="25af7" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myGitField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="563b2" class="javax.swing.JButton" binding="myTestButton">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="2" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<horizontalAlignment value="0"/>
<label resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.test.label"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.test"/>
</properties>
</component>
<component id="5a909" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="f5de9"/>
<text resource-bundle="git4idea/i18n/GitBundle" key="git.vcs.config.ssh.mode"/>
</properties>
</component>
<grid id="97c7d" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="9eafb">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="f5de9" class="javax.swing.JComboBox" binding="mySSHExecutableComboBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
<vspacer id="4c83d">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -22,6 +22,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.vcs.VcsException;
import git4idea.GitVcs;
import git4idea.checkout.branches.GitBranchConfigurations;
import git4idea.i18n.GitBundle;
import org.jetbrains.annotations.NotNull;
@@ -57,6 +58,10 @@ public class GitVcsPanel {
* The confirmation checkbox
*/
private JCheckBox myAskBeforeConversionsCheckBox;
/**
* The if selected, the branches widget is enabled in the status bar
*/
private JCheckBox myEnableBranchesWidgetCheckBox;
/**
* The project
*/
@@ -107,6 +112,7 @@ public class GitVcsPanel {
myConvertTextFilesComboBox.setSelectedItem(CRLF_CONVERT_TO_PROJECT);
myGitField.addBrowseFolderListener(GitBundle.getString("find.git.title"), GitBundle.getString("find.git.description"), project,
new FileChooserDescriptor(true, false, false, false, false, false));
myEnableBranchesWidgetCheckBox.setSelected(GitBranchConfigurations.getInstance(myProject).isWidgetEnabled());
}
/**
@@ -148,6 +154,7 @@ public class GitVcsPanel {
mySSHExecutableComboBox.setSelectedItem(settings.isIdeaSsh() ? IDEA_SSH : NATIVE_SSH);
myAskBeforeConversionsCheckBox.setSelected(settings.askBeforeLineSeparatorConversion());
myConvertTextFilesComboBox.setSelectedItem(crlfPolicyItem(settings));
myEnableBranchesWidgetCheckBox.setSelected(GitBranchConfigurations.getInstance(myProject).isWidgetEnabled());
}
/**
@@ -181,7 +188,8 @@ public class GitVcsPanel {
return !settings.getGitExecutable().equals(myGitField.getText()) ||
(settings.isIdeaSsh() != IDEA_SSH.equals(mySSHExecutableComboBox.getSelectedItem())) ||
!crlfPolicyItem(settings).equals(myConvertTextFilesComboBox.getSelectedItem()) ||
settings.askBeforeLineSeparatorConversion() != myAskBeforeConversionsCheckBox.isSelected();
settings.askBeforeLineSeparatorConversion() != myAskBeforeConversionsCheckBox.isSelected() ||
GitBranchConfigurations.getInstance(myProject).isWidgetEnabled() != myEnableBranchesWidgetCheckBox.isSelected();
}
/**
@@ -205,5 +213,6 @@ public class GitVcsPanel {
}
settings.setLineSeparatorsConversion(conversionPolicy);
settings.setAskBeforeLineSeparatorConversion(myAskBeforeConversionsCheckBox.isSelected());
GitBranchConfigurations.getInstance(myProject).setWidgetEnabled(myEnableBranchesWidgetCheckBox.isSelected());
}
}
@@ -53,7 +53,7 @@ public class HgChangesetStatus extends JLabel implements CustomStatusBarWidget {
return "HgChangeSetStatus";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -62,7 +62,7 @@ public class HgCurrentBranchStatus extends JLabel implements CustomStatusBarWidg
return "HgCurrentBranchStatus";
}
public WidgetPresentation getPresentation(@NotNull Type type) {
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}