From c186908e600651fe6d5d3db33e500cd4abf4fcd2 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 8 Jul 2011 16:06:49 +0400 Subject: [PATCH 01/18] Add method 'entrySet' to MultiMap and use it. --- platform/util/src/com/intellij/util/containers/MultiMap.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index 24886dd148aa..c1bf526fbb92 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -77,6 +77,10 @@ public class MultiMap { list.add(value); } + public Set>> entrySet() { + return myMap.entrySet(); + } + public boolean isEmpty() { for(Collection valueList: myMap.values()) { if (!valueList.isEmpty()) { From f1c0c4c2a4ec0db89f2904320546c59a151bfe20 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 8 Jul 2011 16:16:29 +0400 Subject: [PATCH 02/18] extracted FileDownloader api --- .../ui/libraries/LibraryDownloadSettings.java | 10 +- .../download/DownloadableFileService.java | 15 ++- .../impl/DownloadableFileServiceImpl.java | 15 ++- .../util/download/impl/FileDownloader.java | 31 ++++++ .../download/impl/FileDownloaderImpl.java} | 99 ++++++++++--------- .../src/messages/IdeBundle.properties | 16 +-- 6 files changed, 126 insertions(+), 60 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/util/download/impl/FileDownloader.java rename platform/lang-impl/src/com/intellij/{facet/impl/ui/libraries/LibraryDownloader.java => util/download/impl/FileDownloaderImpl.java} (78%) diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java index c029cd626ac6..2e12030dc85c 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryDownloadSettings.java @@ -15,7 +15,6 @@ */ package com.intellij.facet.impl.ui.libraries; -import com.intellij.util.download.DownloadableFileDescription; import com.intellij.framework.library.DownloadableLibraryType; import com.intellij.framework.library.FrameworkLibraryVersion; import com.intellij.framework.library.LibraryVersionProperties; @@ -23,6 +22,8 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.download.DownloadableFileDescription; +import com.intellij.util.download.DownloadableFileService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -108,9 +109,10 @@ public class LibraryDownloadSettings { @Nullable public NewLibraryEditor download(JComponent parent) { - LibraryDownloader downloader = new LibraryDownloader(mySelectedDownloads, null, parent, myDirectoryForDownloadedLibrariesPath, myLibraryName); - VirtualFile[] files = downloader.download(); - if (files.length != mySelectedDownloads.size()) { + VirtualFile[] files = DownloadableFileService.getInstance().createDownloader(mySelectedDownloads, null, parent, myLibraryName + " Library") + .toDirectory(myDirectoryForDownloadedLibrariesPath) + .download(); + if (files == null) { return null; } diff --git a/platform/lang-impl/src/com/intellij/util/download/DownloadableFileService.java b/platform/lang-impl/src/com/intellij/util/download/DownloadableFileService.java index aa2aba45a14a..002dbf0a9105 100644 --- a/platform/lang-impl/src/com/intellij/util/download/DownloadableFileService.java +++ b/platform/lang-impl/src/com/intellij/util/download/DownloadableFileService.java @@ -16,10 +16,14 @@ package com.intellij.util.download; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.download.impl.FileDownloader; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.net.URL; +import java.util.List; /** * @author nik @@ -33,7 +37,14 @@ public abstract class DownloadableFileService { public abstract DownloadableFileDescription createFileDescription(@NotNull String downloadUrl, @NotNull String fileName); @NotNull - public abstract DownloadableFileSetVersions createFileSetVersions(@NotNull String groupId, @NotNull URL... localUrls); + public abstract DownloadableFileSetVersions createFileSetVersions(@NotNull String groupId, + @NotNull URL... localUrls); - public abstract void loadVersionsToCombobox(@NotNull DownloadableFileSetVersions versions, @NotNull JComboBox comboBox); + @NotNull + public abstract FileDownloader createDownloader(@NotNull DownloadableFileSetDescription description, @Nullable Project project, + JComponent parent); + + @NotNull + public abstract FileDownloader createDownloader(List fileDescriptions, @Nullable Project project, + JComponent parent, @NotNull String presentableDownloadName); } diff --git a/platform/lang-impl/src/com/intellij/util/download/impl/DownloadableFileServiceImpl.java b/platform/lang-impl/src/com/intellij/util/download/impl/DownloadableFileServiceImpl.java index ce496eca5a83..02bcef84454c 100644 --- a/platform/lang-impl/src/com/intellij/util/download/impl/DownloadableFileServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/util/download/impl/DownloadableFileServiceImpl.java @@ -16,12 +16,14 @@ package com.intellij.util.download.impl; import com.intellij.facet.frameworks.beans.Artifact; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.download.DownloadableFileDescription; import com.intellij.util.download.DownloadableFileService; import com.intellij.util.download.DownloadableFileSetDescription; import com.intellij.util.download.DownloadableFileSetVersions; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.net.URL; @@ -49,7 +51,18 @@ public class DownloadableFileServiceImpl extends DownloadableFileService { }; } + @NotNull @Override - public void loadVersionsToCombobox(@NotNull DownloadableFileSetVersions versions, @NotNull JComboBox comboBox) { + public FileDownloader createDownloader(@NotNull DownloadableFileSetDescription description, + @Nullable Project project, + JComponent parent) { + return createDownloader(description.getFiles(), project, parent, description.getName()); + } + + @NotNull + public FileDownloader createDownloader(final List fileDescriptions, + final @Nullable Project project, + JComponent parent, @NotNull String presentableDownloadName) { + return new FileDownloaderImpl(fileDescriptions, project, parent, presentableDownloadName); } } diff --git a/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloader.java b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloader.java new file mode 100644 index 000000000000..c3897c2719d9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloader.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.download.impl; + +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public interface FileDownloader { + @NotNull + FileDownloader toDirectory(@NotNull String directoryForDownloadedFilesPath); + + @Nullable + VirtualFile[] download(); +} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/ui/libraries/LibraryDownloader.java b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java similarity index 78% rename from platform/lang-impl/src/com/intellij/facet/impl/ui/libraries/LibraryDownloader.java rename to platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java index 942e37dd99aa..58a4c0a34586 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/ui/libraries/LibraryDownloader.java +++ b/platform/lang-impl/src/com/intellij/util/download/impl/FileDownloaderImpl.java @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.intellij.facet.impl.ui.libraries; +package com.intellij.util.download.impl; -import com.intellij.util.download.DownloadableFileDescription; import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.Result; @@ -38,11 +37,13 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.download.DownloadableFileDescription; import com.intellij.util.io.UrlConnectionUtil; import com.intellij.util.net.HttpConfigurable; import com.intellij.util.net.IOExceptionDialog; import com.intellij.util.net.NetUtils; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -55,7 +56,7 @@ import java.util.List; /** * @author nik */ -public class LibraryDownloader { +public class FileDownloaderImpl implements FileDownloader { private static final int CONNECTION_TIMEOUT = 60*1000; private static final int READ_TIMEOUT = 60*1000; @NonNls private static final String LIB_SCHEMA = "lib://"; @@ -66,18 +67,24 @@ public class LibraryDownloader { private String myDirectoryForDownloadedFilesPath; private String myDialogTitle; - public LibraryDownloader(final List fileDescriptions, final @Nullable Project project, JComponent parent, - @Nullable String directoryForDownloadedFilePath, @Nullable String libraryPresentableName) { + public FileDownloaderImpl(final List fileDescriptions, + final @Nullable Project project, + JComponent parent, + @NotNull String presentableDownloadName) { myProject = project; myFileDescriptions = fileDescriptions; myParent = parent; - myDirectoryForDownloadedFilesPath = directoryForDownloadedFilePath; - myDialogTitle = IdeBundle.message("progress.download.libraries.title"); - if (libraryPresentableName != null) { - myDialogTitle = IdeBundle.message("progress.download.0.libraries.title", StringUtil.capitalize(libraryPresentableName)); - } + myDialogTitle = IdeBundle.message("progress.download.0.title", StringUtil.capitalize(presentableDownloadName)); } + @NotNull + @Override + public FileDownloader toDirectory(@NotNull String directoryForDownloadedFilesPath) { + myDirectoryForDownloadedFilesPath = directoryForDownloadedFilesPath; + return this; + } + + @Override public VirtualFile[] download() { VirtualFile dir = null; if (myDirectoryForDownloadedFilesPath != null) { @@ -87,21 +94,23 @@ public class LibraryDownloader { } if (dir == null) { - dir = chooseDirectoryForLibraries(); + dir = chooseDirectoryForFiles(); } if (dir != null) { return doDownload(dir); } - return VirtualFile.EMPTY_ARRAY; + return null; } + @Nullable private VirtualFile[] doDownload(final VirtualFile dir) { HttpConfigurable.getInstance().setAuthenticator(); final List> downloadedFiles = new ArrayList>(); - final List existingFiles = new ArrayList(); + final List existingFiles = new ArrayList(); final Ref exceptionRef = Ref.create(null); final Ref currentFile = new Ref(); + final File ioDir = VfsUtil.virtualToIoFile(dir); ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { public void run() { @@ -112,11 +121,11 @@ public class LibraryDownloader { currentFile.set(description); if (indicator != null) { indicator.checkCanceled(); - indicator.setText(IdeBundle.message("progress.0.of.1.file.downloaded.text", i, myFileDescriptions.size())); + indicator.setText(IdeBundle.message("progress.downloading.0.of.1.file.text", i+1, myFileDescriptions.size())); } - final VirtualFile existing = dir.findChild(description.getDefaultFileName()); - long size = existing != null ? existing.getLength() : -1; + final File existing = new File(ioDir, description.getDefaultFileName()); + long size = existing.exists() ? existing.length() : -1; if (!download(description, size, downloadedFiles)) { existingFiles.add(existing); @@ -133,39 +142,39 @@ public class LibraryDownloader { }, myDialogTitle, true, myProject, myParent); Exception exception = exceptionRef.get(); - if (exception == null) { - try { - return moveToDir(existingFiles, downloadedFiles, dir); - } - catch (IOException e) { - if (myProject != null) { - Messages.showErrorDialog(myProject, myDialogTitle, e.getMessage()); + if (exception != null) { + deleteFiles(downloadedFiles); + if (exception instanceof IOException) { + String message = IdeBundle.message("error.file.download.failed", exception.getMessage()); + if (currentFile.get() != null) { + message += ": " + currentFile.get().getDownloadUrl(); } - else { - Messages.showErrorDialog(myParent, myDialogTitle, e.getMessage()); + final boolean tryAgain = IOExceptionDialog.showErrorDialog(myDialogTitle, message); + if (tryAgain) { + return doDownload(dir); } - return VirtualFile.EMPTY_ARRAY; } + return null; } - deleteFiles(downloadedFiles); - if (exception instanceof IOException) { - String message = IdeBundle.message("error.library.download.failed", exception.getMessage()); - if (currentFile.get() != null) { - message += ": " + currentFile.get().getDownloadUrl(); + try { + return moveToDir(existingFiles, downloadedFiles, dir); + } + catch (IOException e) { + if (myProject != null) { + Messages.showErrorDialog(myProject, myDialogTitle, e.getMessage()); } - final boolean tryAgain = IOExceptionDialog.showErrorDialog(myDialogTitle, message); - if (tryAgain) { - return doDownload(dir); + else { + Messages.showErrorDialog(myParent, myDialogTitle, e.getMessage()); } + return null; } - return VirtualFile.EMPTY_ARRAY; } @Nullable - private VirtualFile chooseDirectoryForLibraries() { + private VirtualFile chooseDirectoryForFiles() { final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); - descriptor.setTitle(IdeBundle.message("dialog.directory.for.libraries.title")); + descriptor.setTitle(IdeBundle.message("dialog.directory.for.downloaded.files.title")); final VirtualFile[] files; if (myProject != null) { @@ -178,7 +187,8 @@ public class LibraryDownloader { return files.length > 0 ? files[0] : null; } - private static VirtualFile[] moveToDir(final List existingFiles, final List> downloadedFiles, final VirtualFile dir) throws IOException { + @NotNull + private static VirtualFile[] moveToDir(final List existingFiles, final List> downloadedFiles, final VirtualFile dir) throws IOException { List files = new ArrayList(); final File ioDir = VfsUtil.virtualToIoFile(dir); @@ -201,10 +211,10 @@ public class LibraryDownloader { } } - for (final VirtualFile file : existingFiles) { + for (final File file : existingFiles) { VirtualFile libraryRootFile = new WriteAction() { protected void run(final Result result) { - final String url = VfsUtil.getUrlForLibraryRoot(VfsUtil.virtualToIoFile(file)); + final String url = VfsUtil.getUrlForLibraryRoot(file); result.setResult(VirtualFileManager.getInstance().refreshAndFindFileByUrl(url)); } @@ -213,7 +223,6 @@ public class LibraryDownloader { files.add(libraryRootFile); } } - return VfsUtil.toVirtualFileArray(files); } @@ -241,7 +250,7 @@ public class LibraryDownloader { final String presentableUrl = fileDescription.getPresentableDownloadUrl(); final String url = fileDescription.getDownloadUrl(); if (url.startsWith(LIB_SCHEMA)) { - indicator.setText2(IdeBundle.message("progress.locate.jar.text", fileDescription.getPresentableFileName())); + indicator.setText2(IdeBundle.message("progress.locate.file.text", fileDescription.getPresentableFileName())); final String path = FileUtil.toSystemDependentName(StringUtil.trimStart(url, LIB_SCHEMA)); final File file = PathManager.findFileInLibDirectory(path); downloadedFiles.add(Pair.create(fileDescription, file)); @@ -254,7 +263,7 @@ public class LibraryDownloader { } } else { - indicator.setText2(IdeBundle.message("progress.connecting.to.dowload.jar.text", presentableUrl)); + indicator.setText2(IdeBundle.message("progress.connecting.to.download.file.text", presentableUrl)); indicator.setIndeterminate(true); HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection(); connection.setConnectTimeout(CONNECTION_TIMEOUT); @@ -276,10 +285,10 @@ public class LibraryDownloader { return false; } - tempFile = FileUtil.createTempFile("downloaded", "jar"); + tempFile = FileUtil.createTempFile("downloaded", "file"); input = UrlConnectionUtil.getConnectionInputStreamWithException(connection, indicator); output = new BufferedOutputStream(new FileOutputStream(tempFile)); - indicator.setText2(IdeBundle.message("progress.download.jar.text", fileDescription.getPresentableFileName(), presentableUrl)); + indicator.setText2(IdeBundle.message("progress.download.file.text", fileDescription.getPresentableFileName(), presentableUrl)); indicator.setIndeterminate(size == -1); NetUtils.copyStreamContent(indicator, input, output, size); diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 134c8c9e4f54..da0468993086 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -958,15 +958,15 @@ message.text.creating.deployment.descriptor=Creating Deployment Descriptor button.facet.quickfix.text=&Fix +progress.download.0.title=Downloading {0} +progress.download.file.text=Downloading ''{0}'' from ''{1}''... +progress.connecting.to.download.file.text=Connecting to ''{0}''... +progress.locate.file.text=Locating ''{0}''... +progress.downloading.0.of.1.file.text=Downloading {0} of {1} {1, choice, 1#file|2#files}... +dialog.directory.for.downloaded.files.title=Downloaded files will be copied to selected directory +error.file.download.failed=Downloading failed: {0} + maven.repository.presentable.name=Maven repository -progress.download.libraries.title=Downloading Libraries -progress.download.0.libraries.title=Downloading {0} Libraries -progress.download.jar.text=Downloading ''{0}'' from ''{1}''... -progress.connecting.to.dowload.jar.text=Connecting to ''{0}''... -progress.locate.jar.text=Locating ''{0}''... -progress.0.of.1.file.downloaded.text={0} of {1} files downloaded -dialog.directory.for.libraries.title=Downloaded libraries will be copied to selected directory -error.library.download.failed=Library downloading failed: {0} label.missed.libraries.prefix=The following libraries are missing: label.missed.libraries.text={0}.
Class ''{1}'' not found missing.libraries.fix.button=Fix... From 93141806c9001f34def6b9c24871851cafea1749 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 8 Jul 2011 14:25:48 +0200 Subject: [PATCH 03/18] Fix occasional menu painting glitches on GTK+ L&F --- .../com/intellij/ide/ui/LafManagerImpl.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java index 82c338acb032..f84057fd0a1e 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java @@ -812,7 +812,9 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo PopupUtil.setPopupType(myDelegate, popupType); } - return myDelegate.getPopup(owner, contents, point.x, point.y); + final Popup popup = myDelegate.getPopup(owner, contents, point.x, point.y); + fixPopupSize(popup, contents); + return popup; } private static Point fixPopupLocation(final Component contents, final int x, final int y) { @@ -844,5 +846,22 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo return rec.getLocation(); } + + private static void fixPopupSize(final Popup popup, final Component contents) { + if (!UIUtil.isUnderGTKLookAndFeel() || !(contents instanceof JPopupMenu)) return; + + for (Class aClass = popup.getClass(); aClass != null && Popup.class.isAssignableFrom(aClass); aClass = aClass.getSuperclass()) { + try { + final Method getComponent = aClass.getDeclaredMethod("getComponent"); + getComponent.setAccessible(true); + final Object component = getComponent.invoke(popup); + if (component instanceof JWindow) { + ((JWindow)component).setSize(new Dimension(0, 0)); + } + break; + } + catch (Exception ignored) { } + } + } } } From 043dc645b944a44074812f80d99dab2f1eee6995 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Fri, 8 Jul 2011 17:33:26 +0400 Subject: [PATCH 04/18] PsiViewer - correctly highlihght injected elements in CDATA block --- .../com/intellij/internal/psiView/PsiViewerDialog.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java index 2d8fa2790098..58132d26ea1d 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java @@ -21,6 +21,7 @@ import com.intellij.ide.ui.ListCellRendererWrapper; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.lang.LanguageUtil; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.AccessToken; @@ -692,11 +693,9 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider { ? (PsiElement)elementObject : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null; if (element != null) { - final PsiElement psiElement = FileContextUtil.getFileContext(element.getContainingFile()); - final int textOffset = psiElement == null ? 0 : psiElement.getTextOffset(); - TextRange range = element.getTextRange(); - int start = range.getStartOffset() + textOffset; - int end = range.getEndOffset() + textOffset; + TextRange hostRange = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange()); + int start = hostRange.getStartOffset(); + int end = hostRange.getEndOffset(); final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure(); PsiElement rootPsiElement = treeStructure.getRootPsiElement(); if (rootPsiElement != null) { From e973787f3e40216cf37bbb30f10161405287c0c5 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Fri, 8 Jul 2011 17:46:23 +0400 Subject: [PATCH 05/18] options tree: infinte selection jumping fixed --- .../util/treeView/AbstractTreeBuilder.java | 4 ++++ .../ide/util/treeView/AbstractTreeUi.java | 22 ++++++++++++++++--- .../options/newEditor/OptionsTree.java | 11 ++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java index d40b8486d465..2670b9390488 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java @@ -642,6 +642,10 @@ public class AbstractTreeBuilder implements Disposable { } } + public boolean isSelectionBeingAdjusted() { + return getUi().isSelectionBeingAdjusted(); + } + private void assertDisposed() { assert !isDisposed(); } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index db729b89171d..06c2511b1a68 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -182,6 +182,8 @@ public class AbstractTreeUi { private boolean mySelectionIsAdjusted; private boolean myReleaseRequested; + private boolean mySelectionIsBeingAdjusted; + private final Set myRevalidatedObjects = new HashSet(); private final Set myUserRunnables = new HashSet(); @@ -3713,7 +3715,7 @@ public class AbstractTreeUi { } Set toSelect = new HashSet(); - myTree.clearSelection(); + clearSelection(); ContainerUtil.addAll(toSelect, elements); if (addToSelection) { toSelect.addAll(currentElements); @@ -3734,7 +3736,7 @@ public class AbstractTreeUi { if (wasRootNodeInitialized()) { final int[] originalRows = myTree.getSelectionRows(); if (!addToSelection) { - myTree.clearSelection(); + clearSelection(); } addNext(elementsToSelect, 0, new Runnable() { public void run() { @@ -3760,6 +3762,20 @@ public class AbstractTreeUi { }); } + private void clearSelection() { + mySelectionIsBeingAdjusted = true; + try { + myTree.clearSelection(); + } + finally { + mySelectionIsBeingAdjusted = false; + } + } + + public boolean isSelectionBeingAdjusted() { + return mySelectionIsBeingAdjusted; + } + private void restoreSelection(Set selection) { for (Object each : selection) { DefaultMutableTreeNode node = getNodeForElement(each, false); @@ -4564,7 +4580,7 @@ public class AbstractTreeUi { final UpdaterTreeState state = new UpdaterTreeState(this); myTree.collapsePath(new TreePath(myTree.getModel().getRoot())); - myTree.clearSelection(); + clearSelection(); getRootNode().removeAllChildren(); myRootNodeWasQueuedToInitialize = false; diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java index 8b3091d573bd..9f7264661ee5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java @@ -172,11 +172,20 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl } } + private Configurable myQueuedConfigurable; + ActionCallback queueSelection(final Configurable configurable) { + if (myBuilder.isSelectionBeingAdjusted()) { + return new ActionCallback.Rejected(); + } + final ActionCallback callback = new ActionCallback(); + myQueuedConfigurable = configurable; final Update update = new Update(this) { public void run() { + if (configurable != myQueuedConfigurable) return; + if (configurable == null) { myTree.getSelectionModel().clearSelection(); myContext.fireSelected(null, OptionsTree.this); @@ -185,6 +194,8 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl myBuilder.getReady(this).doWhenDone(new Runnable() { @Override public void run() { + if (configurable != myQueuedConfigurable) return; + final EditorNode editorNode = myConfigurable2Node.get(configurable); FilteringTreeStructure.Node editorUiNode = myBuilder.getVisibleNodeFor(editorNode); if (editorUiNode == null) return; From e69030c52fdf45330e17d2be79affa343cf0a782 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Fri, 8 Jul 2011 17:48:29 +0400 Subject: [PATCH 06/18] Separate LibrarySettingsProvider for platform-based products --- .../ui/LibraryRootsComponentDescriptor.java | 8 --- .../LibrarySettingsProvider.java | 54 +++++++++++++++++++ .../configuration/ProjectSettingsService.java | 8 ++- .../src/META-INF/LangExtensionPoints.xml | 1 + 4 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/LibrarySettingsProvider.java diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java index 5e1c5021a878..11e8fe73e8c1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/LibraryRootsComponentDescriptor.java @@ -45,12 +45,4 @@ public abstract class LibraryRootsComponentDescriptor { return OrderRootType.getAllTypes(); } - /** - * @param project The current project. - * @return A configurable which contains additional library settings in File/Settings. - */ - @Nullable - public Configurable getAdditionalSettingsConfigurable(Project project) { - return null; - } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/LibrarySettingsProvider.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/LibrarySettingsProvider.java new file mode 100644 index 000000000000..5c4164f54569 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/LibrarySettingsProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.LibraryType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Provides configurables for library settings for certain library type (platform-based products). + * @author Rustam Vishnyakov + */ +public abstract class LibrarySettingsProvider { + public static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.librarySettingsProvider"); + + @NotNull + public abstract LibraryType getLibraryType(); + public abstract Configurable getAdditionalSettingsConfigurable(Project project); + + @Nullable + public static Configurable getAdditionalSettingsConfigurable(Project project, LibraryType libType) { + LibrarySettingsProvider provider = forLibraryType(libType); + if (provider == null) return null; + return provider.getAdditionalSettingsConfigurable(project); + } + + @Nullable + public static LibrarySettingsProvider forLibraryType(LibraryType libType) { + for (LibrarySettingsProvider provider : Extensions.getExtensions(EP_NAME)) { + if (provider.getLibraryType().equals(libType)) { + return provider; + } + } + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java index 8392d863415a..08621d9bb3e0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java @@ -76,7 +76,8 @@ public class ProjectSettingsService { Configurable additionalSettingsConfigurable = getLibrarySettingsConfigurable(value); if (additionalSettingsConfigurable != null) { LibraryOrderEntry entry = (LibraryOrderEntry) value.getOrderEntry(); - ShowSettingsUtil.getInstance().showSettingsDialog(entry.getOwnerModule().getProject(), additionalSettingsConfigurable); + ShowSettingsUtil.getInstance() + .showSettingsDialog(entry.getOwnerModule().getProject(), additionalSettingsConfigurable.getDisplayName()); } } @@ -94,10 +95,7 @@ public class ProjectSettingsService { Project project = libOrderEntry.getOwnerModule().getProject(); LibraryType libType = ((LibraryEx)lib).getType(); if (libType != null) { - LibraryRootsComponentDescriptor libComponentDescriptor = libType.createLibraryRootsComponentDescriptor(); - if (libComponentDescriptor != null) { - return libComponentDescriptor.getAdditionalSettingsConfigurable(project); - } + return LibrarySettingsProvider.getAdditionalSettingsConfigurable(project, libType); } } return null; diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 59048e1cf8c1..5ac7dc0a46e1 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -154,6 +154,7 @@ + From b93e7f78339ea270be67a0cd2192f5bb056f9423 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 13:36:21 +0200 Subject: [PATCH 07/18] a failing test for completion undo --- .../codeInsight/completion/JavaAutoPopupTest.groovy | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 7c7df7ceec1c..0570c1d788c7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.completion +import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.completion.impl.CompletionServiceImpl import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler import com.intellij.codeInsight.lookup.Lookup @@ -27,14 +28,15 @@ import com.intellij.ide.ui.UISettings import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.command.undo.UndoManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.editor.actionSystem.EditorActionManager import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.extensions.LoadingOrder +import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.progress.ProgressManager import com.intellij.psi.PsiFile -import com.intellij.codeInsight.CodeInsightSettings /** * @author peter @@ -842,5 +844,14 @@ class LiveComplete { assert myFixture.file.text.contains("innerThing();") } + public void _testCharSelectionUndo() { + myFixture.configureByText "a.java", "class Foo {{ }}" + def editor; + edt { editor = FileEditorManager.getInstance(project).openFile(myFixture.file.virtualFile, false)[0] } + type('ArrStoExce.') + edt { UndoManager.getInstance(project).undo(editor) } + assert myFixture.editor.document.text.contains('ArrStoExce.') + } + } From 1d4aad30b8457fcb2817ede8748467306984df87 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 13:52:00 +0200 Subject: [PATCH 08/18] check in a single place that AutoPopupAlarm phase is still valid --- .../completion/CodeCompletionHandlerBase.java | 7 ++----- .../codeInsight/completion/CompletionPhase.java | 16 +++++++++++++++- .../completion/CompletionProgressIndicator.java | 2 +- .../CompletionAutoPopupHandler.java | 17 ++++------------- .../codeInsight/lookup/impl/TypedHandler.java | 2 +- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 29e09240eb0b..5aeb1e42e733 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -496,16 +496,13 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { final Project project = hostFile.getProject(); if (autopopup) { - final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false); + final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false, hostEditor); CompletionServiceImpl.setCompletionPhase(phase); CompletionAutoPopupHandler.runLaterWithCommitted(project, hostDocument, new Runnable() { @Override public void run() { - if (phase != CompletionServiceImpl.getCompletionPhase()) return; - if (hostEditor.isDisposed()) return; - if (DumbService.getInstance(project).isDumb()) return; - + if (phase.isExpired()) return; doComplete(initContext, hasModifiers, invocationCount, hostFile, hostStartOffset, hostEditor, hostMap); } }); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java index 2494662deeee..3326bd593833 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java @@ -25,8 +25,11 @@ import com.intellij.openapi.editor.event.*; import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.HintListener; import com.intellij.ui.LightweightHint; import com.intellij.util.messages.MessageBusConnection; @@ -66,10 +69,21 @@ public abstract class CompletionPhase implements Disposable { public static class AutoPopupAlarm extends CompletionPhase { final boolean copyCommit; + private final Editor myEditor; + private final Expirable focusStamp; + private final Project myProject; - public AutoPopupAlarm(boolean copyCommit) { + public AutoPopupAlarm(boolean copyCommit, Editor editor) { super(null); this.copyCommit = copyCommit; + myEditor = editor; + myProject = editor.getProject(); + focusStamp = IdeFocusManager.getInstance(myProject).getTimestamp(false); + } + + public boolean isExpired() { + if (ApplicationManager.getApplication().isWriteAccessAllowed()) return false; //it will fail anyway + return CompletionServiceImpl.getCompletionPhase() != this || focusStamp.isExpired() || DumbService.getInstance(myProject).isDumb() || myEditor.isDisposed(); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index b50d49face56..5c98c2bd177a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -591,7 +591,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement public void scheduleRestart() { if (isAutopopupCompletion() && hideAutopopupIfMeaningless()) { - CompletionAutoPopupHandler.scheduleAutoPopup(getProject(), myEditor, getParameters().getOriginalFile()); + CompletionAutoPopupHandler.scheduleAutoPopup(getProject(), myEditor); return; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index d66867da92c1..ceae77adb23d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -26,9 +26,7 @@ import com.intellij.ide.PowerSaveMode; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -84,25 +82,18 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { return Result.CONTINUE; } - scheduleAutoPopup(project, editor, file); + scheduleAutoPopup(project, editor); return Result.STOP; } - public static void scheduleAutoPopup(final Project project, final Editor editor, final PsiFile file) { - final boolean isMainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor() == editor; - - final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false); + public static void scheduleAutoPopup(final Project project, final Editor editor) { + final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false, editor); CompletionServiceImpl.setCompletionPhase(phase); final Runnable request = new Runnable() { @Override public void run() { - if (CompletionServiceImpl.getCompletionPhase() != phase) return; - - if (editor.isDisposed() || isMainEditor && FileEditorManager.getInstance(project).getSelectedTextEditor() != editor) return; - if (ApplicationManager.getApplication().isWriteAccessAllowed()) return; //it will fail anyway - if (DumbService.getInstance(project).isDumb()) return; - + if (phase.isExpired()) return; invokeCompletion(CompletionType.BASIC, false, true, project, editor, 0, false); } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java index c9552348013d..c76ca0c14c8e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java @@ -77,7 +77,7 @@ public class TypedHandler extends TypedActionHandlerBase { }); lookup.appendPrefix(charTyped); if (lookup.isStartCompletionWhenNothingMatches() && lookup.getItems().isEmpty()) { - CompletionAutoPopupHandler.scheduleAutoPopup(editor.getProject(), editor, lookup.getPsiFile()); + CompletionAutoPopupHandler.scheduleAutoPopup(editor.getProject(), editor); } AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStamp); From 4f114b6e1ece0fa6d622477d5f5b403a6c0bd269 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 15:52:45 +0200 Subject: [PATCH 09/18] debugging the test --- .../intellij/codeInsight/completion/JavaAutoPopupTest.groovy | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 0570c1d788c7..ffd80f1e0f62 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -583,6 +583,11 @@ public interface Test { for (i in 0.."iter".size()) { edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } } + if (lookup) { + println lookup.items + println myFixture.editor.document.text + println myFixture.editor.caretModel.offset + } assert !lookup } From 84d917307f76ea7e3052daed6ca3a0bc9f86ef3f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 7 Jul 2011 18:56:14 +0400 Subject: [PATCH 10/18] cleanup --- .../dataFlow/InstructionHandler.java | 24 ------------------- .../IntroduceVariableBase.java | 4 ++-- .../idea/svn/config/CompositeRunnable.java | 4 +++- 3 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionHandler.java diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionHandler.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionHandler.java deleted file mode 100644 index 85b9667789e4..000000000000 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.codeInspection.dataFlow; - -/** - * @author Gregory.Shrago - */ -public interface InstructionHandler { - S createEmptyMemoryState(final T dataFlowRunner); -} diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index adb1b63d7ac0..682cd8b228b7 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -231,7 +231,6 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme if (endOffset <= startOffset) return null; - PsiExpression tempExpr; PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd); if (PsiTreeUtil.getParentOfType(elementAt, PsiExpression.class, false) == null) { elementAt = null; @@ -243,10 +242,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); String text = null; + PsiExpression tempExpr; try { text = file.getText().subSequence(startOffset, endOffset).toString(); String prefix = null; - String suffix = null; String stripped = text; if (startLiteralExpression != null) { final int startExpressionOffset = startLiteralExpression.getTextOffset(); @@ -262,6 +261,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme } } + String suffix = null; if (endLiteralExpression != null) { final int endExpressionOffset = endLiteralExpression.getTextOffset() + endLiteralExpression.getTextLength(); if (endOffset == endExpressionOffset ) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/CompositeRunnable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/CompositeRunnable.java index 12867d7d8b5a..a401acaac31e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/CompositeRunnable.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/CompositeRunnable.java @@ -15,10 +15,12 @@ */ package org.jetbrains.idea.svn.config; +import org.jetbrains.annotations.NotNull; + public class CompositeRunnable implements Runnable { private final Runnable[] myRunnables; - public CompositeRunnable(final Runnable... runnables) { + public CompositeRunnable(@NotNull Runnable... runnables) { myRunnables = runnables; } From 61f85f3287f1a0f259e96759828bb13a768562e7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Jul 2011 12:08:08 +0400 Subject: [PATCH 11/18] cleanup --- .../codeInspection/dataFlow/ControlFlow.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java index cfd4d0816797..10fc81b01787 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java @@ -24,21 +24,20 @@ */ package com.intellij.codeInspection.dataFlow; -import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.instructions.FlushVariableInstruction; +import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiVariable; -import com.intellij.util.containers.HashMap; +import gnu.trove.TObjectIntHashMap; -import java.io.PrintStream; import java.util.ArrayList; public class ControlFlow { private final ArrayList myInstructions = new ArrayList(); - private final HashMap myElementToStartOffsetMap = new HashMap(); - private final HashMap myElementToEndOffsetMap = new HashMap(); + private final TObjectIntHashMap myElementToStartOffsetMap = new TObjectIntHashMap(); + private final TObjectIntHashMap myElementToEndOffsetMap = new TObjectIntHashMap(); private DfaVariableValue[] myFields; private final DfaValueFactory myFactory; @@ -55,11 +54,11 @@ public class ControlFlow { } public void startElement(PsiElement psiElement) { - myElementToStartOffsetMap.put(psiElement, Integer.valueOf(myInstructions.size())); + myElementToStartOffsetMap.put(psiElement, myInstructions.size()); } public void finishElement(PsiElement psiElement) { - myElementToEndOffsetMap.put(psiElement, Integer.valueOf(myInstructions.size())); + myElementToEndOffsetMap.put(psiElement, myInstructions.size()); } public void addInstruction(Instruction instruction) { @@ -73,15 +72,13 @@ public class ControlFlow { } public int getStartOffset(PsiElement element){ - Integer value = myElementToStartOffsetMap.get(element); - if (value == null) return -1; - return value.intValue(); + if (!myElementToStartOffsetMap.containsKey(element)) return -1; + return myElementToStartOffsetMap.get(element); } public int getEndOffset(PsiElement element){ - Integer value = myElementToEndOffsetMap.get(element); - if (value == null) return -1; - return value.intValue(); + if (!myElementToEndOffsetMap.containsKey(element)) return -1; + return myElementToEndOffsetMap.get(element); } public DfaVariableValue[] getFields() { From 79a5cb7afa75f7718ea0f8e29eb79131efd9a7a3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Jul 2011 16:43:37 +0400 Subject: [PATCH 12/18] cleanup --- .../com/intellij/ide/util/treeView/AbstractTreeStructure.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeStructure.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeStructure.java index 9138e9732987..eb925effa63c 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeStructure.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeStructure.java @@ -45,7 +45,7 @@ public abstract class AbstractTreeStructure { } public static class Delegate extends AbstractTreeStructure { - private AbstractTreeStructure myDelegee; + private final AbstractTreeStructure myDelegee; public Delegate(AbstractTreeStructure delegee) { myDelegee = delegee; @@ -93,7 +93,7 @@ public abstract class AbstractTreeStructure { } @Override - public AsyncResult revalidateElement(Object element) { + public AsyncResult revalidateElement(Object element) { return myDelegee.revalidateElement(element); } From a94492aa9bd8e585f355f73d5d98bd03ae1d0249 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Jul 2011 17:05:56 +0400 Subject: [PATCH 13/18] cleanup --- .../src/com/intellij/refactoring/MultiFileTestCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java index 7b790cd5f020..e0541eb667eb 100644 --- a/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java +++ b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java @@ -16,12 +16,12 @@ package com.intellij.refactoring; import com.intellij.codeInsight.CodeInsightTestCase; -import com.intellij.testFramework.IdeaTestUtil; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.annotations.NonNls; @@ -55,7 +55,7 @@ public abstract class MultiFileTestCase extends CodeInsightTestCase { FileDocumentManager.getInstance().saveAllDocuments(); if (myDoCompare) { - IdeaTestUtil.assertDirectoriesEqual(rootDir2, rootDir, IdeaTestUtil.CVS_FILE_FILTER); + PlatformTestUtil.assertDirectoriesEqual(rootDir2, rootDir, PlatformTestUtil.CVS_FILE_FILTER); } } From 51dd2c2ed415be6ab056ac852d0ff725774d22b8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Jul 2011 18:09:35 +0400 Subject: [PATCH 14/18] cleanup --- .../java/AbstractJavaFormatterTest.java | 9 +- .../psi/formatter/java/JavaFormatterTest.java | 214 +++++++++--------- .../codeStyle/CodeStyleManagerImpl.java | 5 +- 3 files changed, 115 insertions(+), 113 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java index cf97370f707a..92680c7ef2f3 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java @@ -35,6 +35,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.LightIdeaTestCase; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import java.io.File; import java.util.EnumMap; @@ -93,11 +94,11 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { doTest(getTestName(false) + ".java", getTestName(false) + "_after.java"); } - public void doTest(String fileNameBefore, String fileNameAfter) throws Exception { + public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) throws Exception { doTextTest(Action.REFORMAT, loadFile(fileNameBefore), loadFile(fileNameAfter)); } - public void doTextTest(final String text, String textAfter) throws IncorrectOperationException { + public void doTextTest(@NonNls final String text, @NonNls String textAfter) throws IncorrectOperationException { doTextTest(Action.REFORMAT, text, textAfter); } @@ -164,7 +165,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { } - public void doMethodTest(final String before, final String after) throws Exception { + public void doMethodTest(@NonNls final String before, @NonNls final String after) throws Exception { doTextTest( Action.REFORMAT, "class Foo{\n" + " void foo() {\n" + before + '\n' + " }\n" + "}", @@ -172,7 +173,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase { ); } - public void doClassTest(final String before, final String after) throws Exception { + public void doClassTest(@NonNls final String before, @NonNls final String after) throws Exception { doTextTest( Action.REFORMAT, "class Foo{\n" + before + '\n' + "}", diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java index bb1ac9826824..c67c61fd9043 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java @@ -13,7 +13,9 @@ import com.intellij.psi.PsiElementFactory; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; /** @@ -39,7 +41,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testLabel1() throws Exception { CodeStyleSettings settings = getSettings(); - settings.LABELED_STATEMENT_WRAP = CodeStyleSettings.WRAP_ALWAYS; + settings.LABELED_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; settings.getIndentOptions(StdFileTypes.JAVA).LABEL_INDENT_ABSOLUTE = true; settings.getIndentOptions(StdFileTypes.JAVA).LABEL_INDENT_SIZE = 0; @@ -53,7 +55,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testNullMethodParameter() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.CALL_PARAMETERS_WRAP = CodeStyleSettings.WRAP_ALWAYS; + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; doTest("NullMethodParameter.java", "NullMethodParameter_after.java"); } @@ -131,10 +133,10 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testIfElse() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.IF_BRACE_FORCE = CodeStyleSettings.DO_NOT_FORCE; - settings.FOR_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_IF_MULTILINE; - settings.WHILE_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_IF_MULTILINE; - settings.DOWHILE_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_IF_MULTILINE; + settings.IF_BRACE_FORCE = CommonCodeStyleSettings.DO_NOT_FORCE; + settings.FOR_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_IF_MULTILINE; + settings.WHILE_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_IF_MULTILINE; + settings.DOWHILE_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_IF_MULTILINE; settings.ELSE_ON_NEW_LINE = true; settings.SPECIAL_ELSE_IF_TREATMENT = false; @@ -152,14 +154,14 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { settings.ALIGN_MULTILINE_PARAMETERS = true; settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; settings.WHILE_ON_NEW_LINE = true; - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTest(); } public void testIfBraces() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.IF_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_ALWAYS; - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.IF_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; settings.KEEP_LINE_BREAKS = false; doTest(); } @@ -198,11 +200,11 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testIf() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTest(); - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTest("If.java", "If.java"); - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; settings.KEEP_LINE_BREAKS = false; doTest("If_after.java", "If.java"); @@ -223,7 +225,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testBinaryOperation() throws IncorrectOperationException { final CodeStyleSettings settings = getSettings(); - String text = "class Foo {\n" + " void foo () {\n" + " xxx = aaa + bbb \n" + " + ccc + eee + ddd;\n" + " }\n" + "}"; + @NonNls String text = "class Foo {\n" + " void foo () {\n" + " xxx = aaa + bbb \n" + " + ccc + eee + ddd;\n" + " }\n" + "}"; settings.ALIGN_MULTILINE_BINARY_OPERATION = true; @@ -354,7 +356,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testBraces() throws Exception { final CodeStyleSettings settings = getSettings(); - final String text = + @NonNls final String text = "class Foo {\n" + "void foo () {\n" + "if (a) {\n" + @@ -363,8 +365,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { "}\n" + "}"; - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; - settings.METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest(text, "\n" + "class Foo {\n" + " void foo() {\n" + @@ -374,8 +376,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest(text, "\n" + "class Foo {\n" + " void foo()\n" + @@ -388,8 +390,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { "}"); - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest(text, "\n" + "class Foo {\n" + " void foo()\n" + @@ -401,8 +403,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest(text, "\n" + "class Foo {\n" + " void foo()\n" + @@ -414,8 +416,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { "}"); - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED2; - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED2; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; doTextTest(text, "\n" + "class Foo {\n" + " void foo()\n" + @@ -427,7 +429,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest("class Foo {\n" + " static{\n" + "foo();\n" + "}" + "}", "class Foo {\n" + " static\n" + " {\n" + " foo();\n" + " }\n" + "}"); @@ -860,7 +862,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { final CodeStyleSettings settings = getSettings(); settings.getIndentOptions(StdFileTypes.JAVA).LABEL_INDENT_ABSOLUTE = true; settings.SPECIAL_ELSE_IF_TREATMENT = true; - settings.FOR_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_ALWAYS; + settings.FOR_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS; myTextRange = new TextRange(59, 121); doTextTest("public class Foo {\n" + " public void foo() {\n" + @@ -905,8 +907,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testBraceOnNewLineIfWrapped() throws Exception { - getSettings().BINARY_OPERATION_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; getSettings().RIGHT_MARGIN = 35; getSettings().ALIGN_MULTILINE_BINARY_OPERATION = true; @@ -933,11 +935,11 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testFirstArgumentWrapping() throws Exception { getSettings().RIGHT_MARGIN = 20; - getSettings().CALL_PARAMETERS_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTextTest("class Foo {\n" + " void foo() {\n" + " fooFooFooFoo(1);" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " fooFooFooFoo(\n" + " 1);\n" + " }\n" + "}"); - getSettings().CALL_PARAMETERS_WRAP = CodeStyleSettings.WRAP_ON_EVERY_ITEM; + getSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; doTextTest("class Foo {\n" + " void foo() {\n" + " fooFooFooFoo(1,2);" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " fooFooFooFoo(\n" + @@ -958,8 +960,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testAssertStatementWrapping() throws Exception { - getSettings().ASSERT_STATEMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().BINARY_OPERATION_WRAP = CodeStyleSettings.DO_NOT_WRAP; + getSettings().ASSERT_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().BINARY_OPERATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; getSettings().RIGHT_MARGIN = 40; final JavaPsiFacade facade = getJavaFacade(); final LanguageLevel effectiveLanguageLevel = LanguageLevelProjectExtension.getInstance(facade.getProject()).getLanguageLevel(); @@ -1003,8 +1005,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testAssertStatementWrapping2() throws Exception { - getSettings().BINARY_OPERATION_WRAP = CodeStyleSettings.DO_NOT_WRAP; - getSettings().ASSERT_STATEMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().BINARY_OPERATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + getSettings().ASSERT_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().RIGHT_MARGIN = 37; final CodeStyleSettings.IndentOptions options = getSettings().getIndentOptions(StdFileTypes.JAVA); @@ -1051,10 +1053,10 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { getSettings().RIGHT_MARGIN = 37; getSettings().ALIGN_MULTILINE_EXTENDS_LIST = true; - getSettings().EXTENDS_KEYWORD_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().EXTENDS_LIST_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().EXTENDS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; - getSettings().ASSERT_STATEMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ASSERT_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ASSERT_STATEMENT_COLON_ON_NEXT_LINE = false; getSettings().ALIGN_MULTILINE_BINARY_OPERATION = true; @@ -1084,7 +1086,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testLBrace() throws Exception { - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; getSettings().RIGHT_MARGIN = 14; doTextTest("class Foo {\n" + " void foo() {\n" + " \n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + "\n" + " }\n" + "}"); @@ -1161,7 +1163,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { result[0] = CodeStyleManager.getInstance(getProject()).reformat(fragment); } catch (IncorrectOperationException e) { - assertTrue(e.getLocalizedMessage(), false); + fail(e.getLocalizedMessage()); } } }); @@ -1192,7 +1194,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testArrayInitializerWrapping() throws Exception { - getSettings().ARRAY_INITIALIZER_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ARRAY_INITIALIZER_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = false; getSettings().RIGHT_MARGIN = 37; @@ -1267,9 +1269,9 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testRemoveLineBreak() throws Exception { getSettings().KEEP_LINE_BREAKS = true; - getSettings().CLASS_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; - getSettings().BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().CLASS_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest("class A\n" + "{\n" + "}", "class A {\n" + "}"); @@ -1367,25 +1369,25 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testStaticBlockBraces() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest("class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}", "class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; doTextTest("class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}", "class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest("class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}", "class Foo {\n" + " static\n" + " {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest("class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}", "class Foo {\n" + " static\n" + " {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED2; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; doTextTest("class Foo {\n" + " static {\n" + " //comment\n" + " i = foo();\n" + " }\n" + "}", "class Foo {\n" + " static\n" + " {\n" + @@ -1398,7 +1400,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testBraces2() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; doTextTest("class Foo {\n" + " void foo() {\n" + " if (clientSocket == null)\n" + @@ -1461,13 +1463,13 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; doTextTest("class Foo{\n" + " /**\n" + " *\n" + " */\n" + " void foo() {\n" + " }\n" + "}", "class Foo {\n" + " /**\n" + " *\n" + " */\n" + " void foo() {\n" + " }\n" + "}"); - getSettings().CLASS_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; doTextTest("/**\n" + " *\n" + " */\n" + "class Foo\n{\n" + "}", "/**\n" + " *\n" + " */\n" + "class Foo {\n" + "}"); @@ -1478,7 +1480,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testSynchronized() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest("class Foo {\n" + " void foo() {\n" + "synchronized (this) {foo();\n" + "}\n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " synchronized (this) {\n" + @@ -1487,7 +1489,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest("class Foo {\n" + " void foo() {\n" + "synchronized (this) {foo();\n" + "}\n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " synchronized (this)\n" + @@ -1497,7 +1499,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { " }\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest("class Foo {\n" + " void foo() {\n" + "synchronized (this) {foo();\n" + "}\n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " synchronized (this)\n" + @@ -1508,7 +1510,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED2; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; doTextTest("class Foo {\n" + " void foo() {\n" + "synchronized (this) {\n" + "foo();\n" + "}\n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " synchronized (this)\n" + @@ -1521,7 +1523,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testNextLineShiftedForBlockStatement() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest("class Foo {\n" + " void foo() {\n" + " if (a)\n" + " foo();\n" + " }\n" + "}", "class Foo {\n" + " void foo() {\n" + " if (a)\n" + " foo();\n" + " }\n" + "}"); @@ -1533,7 +1535,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testLongCallChainAfterElse() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; getSettings().KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true; getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; getSettings().ELSE_ON_NEW_LINE = false; @@ -1697,7 +1699,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testDoNotWrapLBrace() throws IncorrectOperationException { - getSettings().BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; getSettings().RIGHT_MARGIN = 66; doTextTest("public class Test {\n" + " void foo(){\n" + @@ -1715,7 +1717,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testNewLinesAroundArrayInitializer() throws IncorrectOperationException { - getSettings().ARRAY_INITIALIZER_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ARRAY_INITIALIZER_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE = true; getSettings().ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = true; getSettings().RIGHT_MARGIN = 40; @@ -1763,14 +1765,14 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { } public void testLongAnnotationsAreNotWrapped() throws Exception { - getSettings().ARRAY_INITIALIZER_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ARRAY_INITIALIZER_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTest(); } public void testWrapExtendsList() throws Exception { getSettings().RIGHT_MARGIN = 50; - getSettings().EXTENDS_LIST_WRAP = CodeStyleSettings.WRAP_ON_EVERY_ITEM; - getSettings().EXTENDS_KEYWORD_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().EXTENDS_LIST_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + getSettings().EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTextTest("class ColtreDataProvider extends DataProvider, AgentEventListener, ParameterDataEventListener {\n}", "class ColtreDataProvider extends DataProvider,\n" + @@ -1780,7 +1782,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testWrapLongExpression() throws Exception { getSettings().RIGHT_MARGIN = 80; - getSettings().BINARY_OPERATION_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ALIGN_MULTILINE_BINARY_OPERATION = true; doTextTest("class Foo {\n" + " void foo () {\n" + @@ -1798,8 +1800,8 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testDoNotWrapCallChainIfParametersWrapped() throws Exception { getSettings().RIGHT_MARGIN = 87; - getSettings().CALL_PARAMETERS_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().METHOD_CALL_CHAIN_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; //getSettings().PREFER_PARAMETERS_WRAP = true; @@ -1832,7 +1834,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testRightMargin_2() throws Exception { getSettings().RIGHT_MARGIN = 65; - getSettings().ASSIGNMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ASSIGNMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE = true; getSettings().KEEP_LINE_BREAKS = false; @@ -1845,7 +1847,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testRightMargin_3() throws Exception { getSettings().RIGHT_MARGIN = 65; - getSettings().ASSIGNMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ASSIGNMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE = false; getSettings().KEEP_LINE_BREAKS = false; @@ -1909,7 +1911,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { try { codeStyleSettings.RIGHT_MARGIN = 80; codeStyleSettings.KEEP_LINE_BREAKS = false; - codeStyleSettings.METHOD_PARAMETERS_WRAP = CodeStyleSettings.WRAP_ON_EVERY_ITEM; + codeStyleSettings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; doClassTest( "public void foo(String p1,\n" + @@ -1946,7 +1948,7 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { try { codeStyleSettings.RIGHT_MARGIN = 20; - codeStyleSettings.ASSIGNMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + codeStyleSettings.ASSIGNMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doMethodTest( "int i=0; //comment comment", "int i =\n" + @@ -2029,15 +2031,15 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testSCR260() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.IF_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_ALWAYS; - settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.IF_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS; + settings.BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; settings.KEEP_LINE_BREAKS = false; doTest(); } public void testSCR114() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; settings.CATCH_ON_NEW_LINE = true; doTest(); } @@ -2045,7 +2047,7 @@ public void testSCR260() throws Exception { public void testSCR259() throws Exception { myTextRange = new TextRange(36, 60); final CodeStyleSettings settings = getSettings(); - settings.IF_BRACE_FORCE = CodeStyleSettings.FORCE_BRACES_ALWAYS; + settings.IF_BRACE_FORCE = CommonCodeStyleSettings.FORCE_BRACES_ALWAYS; settings.KEEP_LINE_BREAKS = false; doTest(); } @@ -2058,15 +2060,15 @@ public void testSCR260() throws Exception { public void testSCR395() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTest(); } public void testSCR11799() throws Exception { final CodeStyleSettings settings = getSettings(); settings.getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 4; - settings.CLASS_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTest(); } @@ -2078,7 +2080,7 @@ public void testSCR260() throws Exception { public void testSCR879() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTest(); } @@ -2107,7 +2109,7 @@ public void testSCR260() throws Exception { public void testSCR479() throws Exception { final CodeStyleSettings settings = getSettings(); settings.RIGHT_MARGIN = 80; - settings.TERNARY_OPERATION_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + settings.TERNARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTextTest("public class Foo {\n" + " public static void main(String[] args) {\n" + " if (name != null ? !name.equals(that.name) : that.name != null)\n" + @@ -2152,9 +2154,9 @@ public void testSCR260() throws Exception { public void testSCR1535() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; - settings.CLASS_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; - settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + settings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + settings.METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest("public class Foo {\n" + " public int foo() {\n" + " if (a) {\n" + @@ -2175,9 +2177,9 @@ public void testSCR260() throws Exception { public void testSCR970() throws Exception { final CodeStyleSettings settings = getSettings(); - settings.THROWS_KEYWORD_WRAP = CodeStyleSettings.WRAP_ALWAYS; - settings.THROWS_LIST_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - settings.METHOD_PARAMETERS_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + settings.THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + settings.THROWS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTest(); } @@ -2191,18 +2193,18 @@ public void testSCR260() throws Exception { public void test1607() throws Exception { getSettings().RIGHT_MARGIN = 30; - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; getSettings().ALIGN_MULTILINE_PARAMETERS = true; - getSettings().METHOD_PARAMETERS_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; doTextTest("class TEst {\n" + "void foo(A a,B b){ /* compiled code */ }\n" + "}", "class TEst {\n" + " void foo(A a, B b)\n" + " { /* compiled code */ }\n" + "}"); } public void testSCR1615() throws Exception { - getSettings().CLASS_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest( "public class ZZZZ \n" + @@ -2231,15 +2233,15 @@ public void testSCR260() throws Exception { } public void testSCR524() throws Exception { - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; getSettings().KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; doTextTest("class Foo {\n" + " void foo() { return;}" + "}", "class Foo {\n" + " void foo() { return;}\n" + "}"); - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED2; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = false; getSettings().KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; - getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.END_OF_LINE; doTextTest("class Foo{\n" + "void foo() {\n" + @@ -2268,8 +2270,8 @@ public void testSCR260() throws Exception { public void testSCR3062() throws Exception { getSettings().KEEP_LINE_BREAKS = false; - getSettings().METHOD_CALL_CHAIN_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().CALL_PARAMETERS_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; getSettings().RIGHT_MARGIN = 80; @@ -2328,7 +2330,7 @@ public void testSCR260() throws Exception { public void testSCR1701() throws Exception { getSettings().SPACE_WITHIN_METHOD_CALL_PARENTHESES = true; getSettings().SPACE_WITHIN_METHOD_PARENTHESES = false; - getSettings().CALL_PARAMETERS_WRAP = CodeStyleSettings.DO_NOT_WRAP; + getSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; getSettings().CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = true; getSettings().CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = true; doTextTest("class Foo {\n" + " void foo() {\n" + " foo(a,b);" + " }\n" + "}", @@ -2336,7 +2338,7 @@ public void testSCR260() throws Exception { } public void testSCR1703() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; doTextTest("class Foo{\n" + " void foo() {\n" + " for (Object o : localizations) {\n" + @@ -2365,7 +2367,7 @@ public void testSCR260() throws Exception { } public void testSCR1795() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; doTextTest("public class Test {\n" + " public static void main(String[] args) {\n" + " do {\n" + @@ -2393,8 +2395,8 @@ public void testSCR260() throws Exception { public void test1980() throws Exception { getSettings().RIGHT_MARGIN = 144; - getSettings().TERNARY_OPERATION_WRAP = CodeStyleSettings.WRAP_ON_EVERY_ITEM; - getSettings().METHOD_CALL_CHAIN_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().TERNARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + getSettings().METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().ALIGN_MULTILINE_TERNARY_OPERATION = true; getSettings().TERNARY_OPERATION_SIGNS_ON_NEXT_LINE = true; doTextTest("class Foo{\n" + @@ -2445,7 +2447,7 @@ public void testSCR260() throws Exception { } public void testSCR2132() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_IF_WRAPPED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; getSettings().ELSE_ON_NEW_LINE = true; doTextTest("class Foo {\n" + @@ -2496,7 +2498,7 @@ public void testSCR260() throws Exception { } public void testSCR2241() throws Exception { - getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; + getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; getSettings().SPECIAL_ELSE_IF_TREATMENT = true; getSettings().ELSE_ON_NEW_LINE = true; doTextTest("class Foo {\n" + @@ -2521,8 +2523,8 @@ public void testSCR260() throws Exception { } public void testSCRIDEA_4783() throws IncorrectOperationException { - getSettings().ASSIGNMENT_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; - getSettings().METHOD_CALL_CHAIN_WRAP = CodeStyleSettings.WRAP_AS_NEEDED; + getSettings().ASSIGNMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings().METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; getSettings().RIGHT_MARGIN = 80; doTextTest("class Foo{\n" + @@ -2884,7 +2886,7 @@ public void testSCR260() throws Exception { */ public void testIDEADEV_23551() throws IncorrectOperationException { - getSettings().BINARY_OPERATION_WRAP = CodeStyleSettings.WRAP_ON_EVERY_ITEM; + getSettings().BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; getSettings().RIGHT_MARGIN = 60; doTextTest("public class Wrapping {\n" + @@ -2905,7 +2907,7 @@ public void testSCR260() throws Exception { } public void testIDEADEV_22967() throws IncorrectOperationException { - getSettings().METHOD_ANNOTATION_WRAP = CodeStyleSettings.WRAP_ALWAYS; + getSettings().METHOD_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; doTextTest("public interface TestInterface {\n" + "\n" + @@ -2941,7 +2943,7 @@ public void testSCR260() throws Exception { } public void testIDEADEV_22967_2() throws IncorrectOperationException { - getSettings().METHOD_ANNOTATION_WRAP = CodeStyleSettings.WRAP_ALWAYS; + getSettings().METHOD_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; doTextTest("public interface TestInterface {\n" + " @Deprecated\n" + " void parametrizedAnnotated(T data);\n" + "}", "public interface TestInterface {\n" + " @Deprecated\n" + " void parametrizedAnnotated(T data);\n" + "}"); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 4c129be534b1..eec19be9e425 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -126,9 +126,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager { } private static void transformAllChildren(final ASTNode file) { - for (ASTNode child = file.getFirstChildNode(); child != null; child = child.getTreeNext()) { - transformAllChildren(child); - } + ((TreeElement)file).acceptTree(new RecursiveTreeElementWalkingVisitor() { + }); } From d6d1436c7ba206c55fef0664cf3c484b4a4fb6aa Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 16:17:15 +0200 Subject: [PATCH 15/18] some inlines --- .../CompletionProgressIndicator.java | 4 ++-- .../CompletionAutoPopupHandler.java | 22 +++++-------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 5c98c2bd177a..d8d858c11a23 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -619,8 +619,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement closeAndFinish(false); - CompletionAutoPopupHandler.invokeCompletion(myParameters.getCompletionType(), false, - isAutopopupCompletion(), project, myEditor, myParameters.getInvocationCount(), false); + CompletionAutoPopupHandler.invokeCompletion(myParameters.getCompletionType(), + isAutopopupCompletion(), project, myEditor, myParameters.getInvocationCount()); } }); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index ceae77adb23d..8aae01ccdec3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -94,7 +94,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { @Override public void run() { if (phase.isExpired()) return; - invokeCompletion(CompletionType.BASIC, false, true, project, editor, 0, false); + invokeCompletion(CompletionType.BASIC, true, project, editor, 0); } }; AutoPopupController.getInstance(project).invokeAutoPopupRunnable(new Runnable() { @@ -105,20 +105,9 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { }, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); } - public static void invokeAutoPopupCompletion(final Project project, final Editor editor, Condition condition) { + public static void invokeAutoPopupCompletion(final Project project, final Editor editor, final Condition condition) { ApplicationManager.getApplication().assertIsDispatchThread(); - completeWhenAllDocumentsCommitted(project, editor, CompletionType.BASIC, false, true, 0, false, condition); - } - - private static void completeWhenAllDocumentsCommitted(@NotNull final Project project, - @NotNull final Editor editor, - final CompletionType completionType, - final boolean invokedExplicitly, - final boolean autopopup, - final int time, - final boolean hasModifiers, - final Condition condition) { final Document document = editor.getDocument(); final long beforeStamp = document.getModificationStamp(); final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); @@ -141,7 +130,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { } PsiFile file = documentManager.getPsiFile(document); if (file != null && condition != null && !condition.value(file)) return; - invokeCompletion(completionType, invokedExplicitly, autopopup, project, editor, time, hasModifiers); + invokeCompletion(CompletionType.BASIC, true, project, editor, 0); } }, project.getDisposed()); } @@ -149,9 +138,8 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { } public static void invokeCompletion(CompletionType completionType, - boolean invokedExplicitly, boolean autopopup, - Project project, Editor editor, int time, boolean hasModifiers) { + Project project, Editor editor, int time) { // retrieve the injected file from scratch since our typing might have destroyed the old one completely Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(editor); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(topLevelEditor.getDocument()); @@ -161,7 +149,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { PsiDocumentManager.getInstance(project).commitAllDocuments(); Editor newEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(topLevelEditor, topLevelFile); try { - new CodeCompletionHandlerBase(completionType, invokedExplicitly, autopopup).invokeCompletion(project, newEditor, time, hasModifiers); + new CodeCompletionHandlerBase(completionType, false, autopopup).invokeCompletion(project, newEditor, time, false); } catch (IndexNotReadyException ignored) { } From ae1cdf679211de21bfeb125c3c81496d27cf3eb2 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 16:28:53 +0200 Subject: [PATCH 16/18] a more unified API for autopopup invocation --- .../codeInsight/AutoPopupController.java | 13 ++--- .../CompletionProgressIndicator.java | 2 +- .../CompletionAutoPopupHandler.java | 50 +++++-------------- .../codeInsight/lookup/impl/TypedHandler.java | 2 +- 4 files changed, 18 insertions(+), 49 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java index 4dd4eadfc919..35c685422204 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java @@ -90,17 +90,12 @@ public class AutoPopupController implements Disposable { final CodeInsightSettings settings = CodeInsightSettings.getInstance(); if (settings.AUTO_POPUP_COMPLETION_LOOKUP) { - final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject); - if (file == null) return; + if (PsiUtilBase.getPsiFileInEditor(editor, myProject) == null) return; final Runnable request = new Runnable(){ public void run(){ - if (myProject.isDisposed()) return; - if (editor.isDisposed()) return; - - //PsiDocumentManager.getInstance(myProject).commitAllDocuments(); - if (!file.isValid()) return; - - CompletionAutoPopupHandler.invokeAutoPopupCompletion(myProject, editor, condition); + if (!myProject.isDisposed() && !editor.isDisposed()) { + CompletionAutoPopupHandler.scheduleAutoPopup(editor, condition); + } } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index d8d858c11a23..dda1b66d3b7e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -591,7 +591,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement public void scheduleRestart() { if (isAutopopupCompletion() && hideAutopopupIfMeaningless()) { - CompletionAutoPopupHandler.scheduleAutoPopup(getProject(), myEditor); + CompletionAutoPopupHandler.scheduleAutoPopup(myEditor, null); return; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index 8aae01ccdec3..ecf9e4ba8799 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -35,6 +35,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.PsiDocumentManagerImpl; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author peter @@ -82,59 +83,32 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { return Result.CONTINUE; } - scheduleAutoPopup(project, editor); + scheduleAutoPopup(editor, null); return Result.STOP; } - public static void scheduleAutoPopup(final Project project, final Editor editor) { + public static void scheduleAutoPopup(final Editor editor, @Nullable final Condition condition) { + final Project project = editor.getProject(); + assert project != null; final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false, editor); CompletionServiceImpl.setCompletionPhase(phase); - final Runnable request = new Runnable() { - @Override - public void run() { - if (phase.isExpired()) return; - invokeCompletion(CompletionType.BASIC, true, project, editor, 0); - } - }; AutoPopupController.getInstance(project).invokeAutoPopupRunnable(new Runnable() { @Override public void run() { - runLaterWithCommitted(project, editor.getDocument(), request); - } - }, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); - } - - public static void invokeAutoPopupCompletion(final Project project, final Editor editor, final Condition condition) { - ApplicationManager.getApplication().assertIsDispatchThread(); - - final Document document = editor.getDocument(); - final long beforeStamp = document.getModificationStamp(); - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); - documentManager.cancelAndRunWhenAllCommitted("start completion when all docs committed", new Runnable() { - @Override - public void run() { - long afterStamp = document.getModificationStamp(); - if (beforeStamp != afterStamp) { - // no luck, will try later - return; - } - // later because we may end up in write action here if there was a synchronous commit - ApplicationManager.getApplication().invokeLater(new Runnable() { + runLaterWithCommitted(project, editor.getDocument(), new Runnable() { @Override public void run() { - long afterStamp = document.getModificationStamp(); - if (beforeStamp != afterStamp) { - // no luck, will try later - return; - } - PsiFile file = documentManager.getPsiFile(document); + if (phase.isExpired()) return; + + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); if (file != null && condition != null && !condition.value(file)) return; + invokeCompletion(CompletionType.BASIC, true, project, editor, 0); } - }, project.getDisposed()); + }); } - }); + }, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); } public static void invokeCompletion(CompletionType completionType, diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java index c76ca0c14c8e..9cb628f1c290 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java @@ -77,7 +77,7 @@ public class TypedHandler extends TypedActionHandlerBase { }); lookup.appendPrefix(charTyped); if (lookup.isStartCompletionWhenNothingMatches() && lookup.getItems().isEmpty()) { - CompletionAutoPopupHandler.scheduleAutoPopup(editor.getProject(), editor); + CompletionAutoPopupHandler.scheduleAutoPopup(editor, null); } AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStamp); From 67d0f6c20b589afb2714596c72b3db124bcf9d26 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 8 Jul 2011 17:43:34 +0200 Subject: [PATCH 17/18] more test debugging --- .../intellij/codeInsight/completion/JavaAutoPopupTest.groovy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index ffd80f1e0f62..1be2d92aa0fc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -582,6 +582,8 @@ public interface Test { for (i in 0.."iter".size()) { edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } + println myFixture.editor.caretModel.offset + println myFixture.editor.document.text[myFixture.editor.caretModel.offset] } if (lookup) { println lookup.items From 6cb6e67ddb14592fca6148b6f87a493e55994461 Mon Sep 17 00:00:00 2001 From: irengrig Date: Fri, 8 Jul 2011 19:42:11 +0400 Subject: [PATCH 18/18] git log structure chooser --- .../configuration/ContentEntryTreeEditor.java | 2 +- .../com/intellij/ui/CollectionListModel.java | 10 + .../fileChooser/ex/FileSystemTreeImpl.java | 23 +- .../vcs/changes/ui/ChangesTreeList.java | 64 +-- .../ui/VirtualFileListCellRenderer.java | 100 ++++ .../treeWithCheckedNodes/SelectedState.java | 6 + .../SelectionManager.java | 71 ++- .../src/git4idea/changes/GitChangeUtils.java | 5 +- .../git4idea/history/GitHistoryProvider.java | 2 +- .../src/git4idea/history/GitHistoryUtils.java | 30 +- .../history/browser/ChangesFilter.java | 57 ++- .../history/browser/LowLevelAccessImpl.java | 10 +- .../history/wholeTree/ByRootLoader.java | 16 +- .../history/wholeTree/GitLogFilters.java | 27 +- .../git4idea/history/wholeTree/GitLogUI.java | 75 ++- .../history/wholeTree/LoadController.java | 10 +- .../history/wholeTree/LoaderAndRefresher.java | 3 - .../wholeTree/LoaderAndRefresherImpl.java | 36 +- .../wholeTree/StructureFilterAction.java | 96 ++++ .../history/wholeTree/StructureFilterI.java | 31 ++ .../wholeTree/VcsStructureChooser.java | 457 ++++++++++++++++++ .../git4idea/tests/GitHistoryUtilsTest.java | 2 +- 22 files changed, 997 insertions(+), 136 deletions(-) create mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VirtualFileListCellRenderer.java create mode 100644 plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java create mode 100644 plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterI.java create mode 100644 plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java index a6326de4eaf0..148fa8c5a243 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java @@ -160,7 +160,7 @@ public class ContentEntryTreeEditor { }; - myFileSystemTree = new FileSystemTreeImpl(myProject, myDescriptor, myTree, getContentEntryCellRenderer(), init) { + myFileSystemTree = new FileSystemTreeImpl(myProject, myDescriptor, myTree, getContentEntryCellRenderer(), init, null) { protected AbstractTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, AbstractTreeStructure treeStructure, Comparator comparator, FileChooserDescriptor descriptor, final Runnable onInitialized) { diff --git a/platform/platform-api/src/com/intellij/ui/CollectionListModel.java b/platform/platform-api/src/com/intellij/ui/CollectionListModel.java index 82d707427ce0..13fea2fd8cc6 100644 --- a/platform/platform-api/src/com/intellij/ui/CollectionListModel.java +++ b/platform/platform-api/src/com/intellij/ui/CollectionListModel.java @@ -18,6 +18,8 @@ package com.intellij.ui; import javax.swing.*; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -74,4 +76,12 @@ public class CollectionListModel extends AbstractListModel { int i = myItems.indexOf(element); fireContentsChanged(this, i, i); } + + public void sort(final Comparator comparator) { + Collections.sort(myItems, comparator); + } + + public List getItems() { + return Collections.unmodifiableList(myItems); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java index 575cbd0c5e8b..3407d47cd246 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java @@ -17,7 +17,6 @@ package com.intellij.openapi.fileChooser.ex; import com.intellij.ide.util.treeView.AbstractTreeBuilder; import com.intellij.ide.util.treeView.AbstractTreeStructure; -import com.intellij.ide.util.treeView.AbstractTreeUi; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionGroup; @@ -39,11 +38,14 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.*; +import com.intellij.ui.PopupHandler; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.UIBundle; import com.intellij.ui.treeStructure.SimpleNodeRenderer; +import com.intellij.ui.treeStructure.Tree; import com.intellij.util.containers.ConvertingIterator; import com.intellij.util.containers.Convertor; -import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.Nullable; @@ -73,13 +75,14 @@ public class FileSystemTreeImpl implements FileSystemTree { private final MyExpansionListener myExpansionListener = new MyExpansionListener(); public FileSystemTreeImpl(@Nullable Project project, FileChooserDescriptor descriptor) { - this(project, descriptor, new Tree(), null, null); + this(project, descriptor, new Tree(), null, null, null); myTree.setRootVisible(descriptor.isTreeRootVisible()); myTree.setShowsRootHandles(true); } public FileSystemTreeImpl(@Nullable Project project, FileChooserDescriptor descriptor, Tree tree, TreeCellRenderer renderer, - final Runnable onInitialized) { + final Runnable onInitialized, + Convertor speedSearchConvertor) { myProject = project; myTreeStructure = new FileTreeStructure(project, descriptor); myDescriptor = descriptor; @@ -114,7 +117,11 @@ public class FileSystemTreeImpl implements FileSystemTree { } }); - new TreeSpeedSearch(myTree); + if (speedSearchConvertor != null) { + new TreeSpeedSearch(myTree, speedSearchConvertor); + } else { + new TreeSpeedSearch(myTree); + } myTree.setLineStyleAngled(); TreeUtil.installActions(myTree); @@ -220,6 +227,10 @@ public class FileSystemTreeImpl implements FileSystemTree { } } + public AbstractTreeBuilder getTreeBuilder() { + return myTreeBuilder; + } + /** * @deprecated since tree updating is an asynchronous operation */ diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java index 453ebc59aafd..1760be6b98a0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java @@ -27,12 +27,9 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangesUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.ui.components.panels.NonOpaquePanel; @@ -52,7 +49,6 @@ import javax.swing.border.Border; import javax.swing.tree.*; import java.awt.*; import java.awt.event.*; -import java.io.File; import java.util.*; import java.util.List; @@ -640,50 +636,32 @@ public abstract class ChangesTreeList extends JPanel { public MyListCellRenderer() { super(new BorderLayout()); myCheckbox = new JCheckBox(); - myTextRenderer = new ColoredListCellRenderer() { - protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { - final FilePath path = TreeModelBuilder.getPathForObject(value); - if (path.isDirectory()) { - setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON); - } else { - setIcon(path.getFileType().getIcon()); - } - final FileStatus fileStatus; - if (value instanceof Change) { - fileStatus = ((Change) value).getFileStatus(); - } - else { - final VirtualFile virtualFile = path.getVirtualFile(); - if (virtualFile != null) { - fileStatus = FileStatusManager.getInstance(myProject).getStatus(virtualFile); - } - else { - fileStatus = FileStatus.NOT_CHANGED; - } - } - append(path.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, fileStatus.getColor(), null)); + myTextRenderer = new VirtualFileListCellRenderer(myProject) { + @Override + protected void putParentPath(Object value, FilePath path, FilePath self) { + super.putParentPath(value, path, self); final boolean applyChangeDecorator = (value instanceof Change) && myChangeDecorator != null; - final File parentFile = path.getIOFile().getParentFile(); - if (parentFile != null) { - final String parentPath = parentFile.getPath(); - List> parts = null; - if (applyChangeDecorator) { - parts = myChangeDecorator.stressPartsOfFileName((Change)value, parentPath); - } - if (parts == null) { - parts = Collections.singletonList(new Pair(parentPath, ChangeNodeDecorator.Stress.PLAIN)); - } - - append(" ("); - for (Pair part : parts) { - append(part.getFirst(), part.getSecond().derive(SimpleTextAttributes.GRAYED_ATTRIBUTES)); - } - append(")", SimpleTextAttributes.GRAYED_ATTRIBUTES); - } if (applyChangeDecorator) { myChangeDecorator.decorate((Change) value, this, isShowFlatten()); } } + + @Override + protected void putParentPathImpl(Object value, String parentPath, FilePath self) { + final boolean applyChangeDecorator = (value instanceof Change) && myChangeDecorator != null; + List> parts = null; + if (applyChangeDecorator) { + parts = myChangeDecorator.stressPartsOfFileName((Change)value, parentPath); + } + if (parts == null) { + super.putParentPathImpl(value, parentPath, self); + return; + } + + for (Pair part : parts) { + append(part.getFirst(), part.getSecond().derive(SimpleTextAttributes.GRAYED_ATTRIBUTES)); + } + } }; myCheckbox.setBackground(null); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VirtualFileListCellRenderer.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VirtualFileListCellRenderer.java new file mode 100644 index 000000000000..6f146ae7c556 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VirtualFileListCellRenderer.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs.changes.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.PlatformIcons; + +import javax.swing.*; +import java.io.File; + +/** + * @author irengrig + * Date: 7/8/11 + * Time: 12:21 PM + */ +public class VirtualFileListCellRenderer extends ColoredListCellRenderer { + private final FileStatusManager myFileStatusManager; + private final boolean myIgnoreFileStatus; + + public VirtualFileListCellRenderer(final Project project) { + this(project, false); + } + + public VirtualFileListCellRenderer(final Project project, final boolean ignoreFileStatus) { + myIgnoreFileStatus = ignoreFileStatus; + myFileStatusManager = FileStatusManager.getInstance(project); + } + + @Override + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + final FilePath path = TreeModelBuilder.getPathForObject(value); + renderIcon(path); + final FileStatus fileStatus = myIgnoreFileStatus ? FileStatus.NOT_CHANGED : getStatus(value, path); + append(getName(path), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, fileStatus.getColor(), null)); + putParentPath(value, path, path); + } + + protected String getName(FilePath path) { + return path.getName(); + } + + protected FileStatus getStatus(Object value, FilePath path) { + final FileStatus fileStatus; + if (value instanceof Change) { + fileStatus = ((Change) value).getFileStatus(); + } + else { + final VirtualFile virtualFile = path.getVirtualFile(); + if (virtualFile != null) { + fileStatus = myFileStatusManager.getStatus(virtualFile); + } + else { + fileStatus = FileStatus.NOT_CHANGED; + } + } + return fileStatus; + } + + protected void renderIcon(FilePath path) { + if (path.isDirectory()) { + setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON); + } else { + setIcon(path.getFileType().getIcon()); + } + } + + protected void putParentPath(Object value, FilePath path, FilePath self) { + final File parentFile = path.getIOFile().getParentFile(); + if (parentFile != null) { + final String parentPath = parentFile.getPath(); + append(" (", SimpleTextAttributes.GRAYED_ATTRIBUTES); + putParentPathImpl(value, parentPath, self); + append(")", SimpleTextAttributes.GRAYED_ATTRIBUTES); + } + } + + protected void putParentPathImpl(Object value, String parentPath, FilePath self) { + append(parentPath, SimpleTextAttributes.GRAYED_ATTRIBUTES); + } +} diff --git a/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectedState.java b/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectedState.java index 76fd0120a5e5..3267b2bdf48e 100644 --- a/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectedState.java +++ b/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectedState.java @@ -22,6 +22,7 @@ import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -91,4 +92,9 @@ public class SelectedState { public Set getSelected() { return Collections.unmodifiableSet(mySelected); } + + public void setSelection(Collection files) { + mySelected.clear(); + mySelected.addAll(files); + } } diff --git a/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectionManager.java b/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectionManager.java index c5daa37a0793..9a53d07f9dd7 100644 --- a/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectionManager.java +++ b/platform/vcs-impl/src/com/intellij/util/treeWithCheckedNodes/SelectionManager.java @@ -16,14 +16,20 @@ package com.intellij.util.treeWithCheckedNodes; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vcs.impl.CollectionsDelta; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PairProcessor; +import com.intellij.util.PlusMinus; import com.intellij.util.Processor; import com.intellij.util.TreeNodeState; import com.intellij.util.containers.Convertor; +import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; /** * @author irengrig @@ -35,6 +41,8 @@ import javax.swing.tree.DefaultMutableTreeNode; public class SelectionManager { private final SelectedState myState; private final Convertor myNodeConvertor; + @Nullable + private PlusMinus mySelectionChangeListener; public SelectionManager(int selectedSize, int queueSize, final Convertor nodeConvertor) { myNodeConvertor = nodeConvertor; @@ -43,14 +51,17 @@ public class SelectionManager { public void toggleSelection(final DefaultMutableTreeNode node) { final StateWorker stateWorker = new StateWorker(node, myNodeConvertor); - if (stateWorker.getVf() == null) return; + final VirtualFile vf = stateWorker.getVf(); + if (vf == null) return; final TreeNodeState state = getStateImpl(stateWorker); if (TreeNodeState.HAVE_SELECTED_ABOVE.equals(state)) return; if (TreeNodeState.CLEAR.equals(state) && (! myState.canAddSelection())) return; + final HashSet old = new HashSet(myState.getSelected()); + final TreeNodeState futureState = - myState.putAndPass(stateWorker.getVf(), TreeNodeState.SELECTED.equals(state) ? TreeNodeState.CLEAR : TreeNodeState.SELECTED); + myState.putAndPass(vf, TreeNodeState.SELECTED.equals(state) ? TreeNodeState.CLEAR : TreeNodeState.SELECTED); // for those possibly duplicate nodes (i.e. when we have root for module and root for VCS root, each file is shown twice in a tree -> // clear all suspicious cached) @@ -58,7 +69,7 @@ public class SelectionManager { myState.clearAllCachedMatching(new Processor() { @Override public boolean process(VirtualFile virtualFile) { - return VfsUtil.isAncestor(virtualFile, stateWorker.getVf(), false); + return VfsUtil.isAncestor(virtualFile, vf, false); } }); } @@ -73,6 +84,7 @@ public class SelectionManager { return true; } }); + // todo vf, vf - what is correct? myState.clearAllCachedMatching(new Processor() { @Override public boolean process(VirtualFile vf) { @@ -84,6 +96,38 @@ public class SelectionManager { myState.remove(selected); } } + final Set selectedAfter = myState.getSelected(); + if (mySelectionChangeListener != null && ! old.equals(selectedAfter)) { + final Set removed = CollectionsDelta.notInSecond(old, selectedAfter); + final Set newlyAdded = CollectionsDelta.notInSecond(selectedAfter, old); + if (newlyAdded != null) { + for (VirtualFile file : newlyAdded) { + if (mySelectionChangeListener != null) { + mySelectionChangeListener.plus(file); + } + } + } + if (removed != null) { + for (VirtualFile file : removed) { + if (mySelectionChangeListener != null) { + mySelectionChangeListener.minus(file); + } + } + } + } + } + + public boolean canAddSelection() { + return myState.canAddSelection(); + } + + public void setSelection(Collection files) { + myState.setSelection(files); + for (VirtualFile file : files) { + if (mySelectionChangeListener != null) { + mySelectionChangeListener.plus(file); + } + } } public TreeNodeState getState(final DefaultMutableTreeNode node) { @@ -120,6 +164,19 @@ public class SelectionManager { return TreeNodeState.CLEAR; } + public void removeSelection(final VirtualFile elementAt) { + myState.remove(elementAt); + myState.clearAllCachedMatching(new Processor() { + @Override + public boolean process(VirtualFile virtualFile) { + return VfsUtil.isAncestor(virtualFile, elementAt, false) || VfsUtil.isAncestor(elementAt, virtualFile, false); + } + }); + if (mySelectionChangeListener != null) { + mySelectionChangeListener.minus(elementAt); + } + } + private static class StateWorker { private final DefaultMutableTreeNode myNode; private final Convertor myConvertor; @@ -148,4 +205,12 @@ public class SelectionManager { } } } + + public PlusMinus getSelectionChangeListener() { + return mySelectionChangeListener; + } + + public void setSelectionChangeListener(PlusMinus selectionChangeListener) { + mySelectionChangeListener = selectionChangeListener; + } } diff --git a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java index 9ee650711da9..3e88c30499aa 100644 --- a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java +++ b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java @@ -304,12 +304,15 @@ public class GitChangeUtils { @Nullable public static SHAHash commitExists(final Project project, final VirtualFile root, final String anyReference, - final String... parameters) { + List paths, final String... parameters) { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); h.setNoSSH(true); h.setSilent(true); h.addParameters(parameters); h.addParameters("--max-count=1", "--pretty=%H", "--encoding=UTF-8", anyReference, "--"); + if (paths != null && ! paths.isEmpty()) { + h.addRelativeFiles(paths); + } try { final String output = h.run().trim(); if (StringUtil.isEmptyOrSpaces(output)) return null; diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java index 53d34e68f409..6963eef9ca00 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java @@ -166,7 +166,7 @@ public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHisto final VirtualFile root = GitUtil.getGitRoot(filePath); if (root == null) return false; - final SHAHash shaHash = GitChangeUtils.commitExists(myProject, root, beforeVersionId, "--all"); + final SHAHash shaHash = GitChangeUtils.commitExists(myProject, root, beforeVersionId, null, "--all"); if (shaHash == null) { throw new VcsException("Can not apply patch to " + filePath.getPath() + ".\nCan not find revision '" + beforeVersionId + "'."); } diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 7574d621557a..86ddc5d4a2dc 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -410,11 +410,11 @@ public class GitHistoryUtils { } public static void historyWithLinks(final Project project, - FilePath path, - final SymbolicRefs refs, - final AsynchConsumer gitCommitConsumer, - final Getter isCanceled, - final String... parameters) throws VcsException { + FilePath path, + final SymbolicRefs refs, + final AsynchConsumer gitCommitConsumer, + final Getter isCanceled, + Collection paths, final String... parameters) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); @@ -425,9 +425,14 @@ public class GitHistoryUtils { h.setStdoutSuppressed(true); h.addParameters(parameters); parser.parseStatusBeforeName(true); - h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8", "--full-history", "--sparse"); + h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8", "--full-history"); h.endOptions(); - h.addRelativePaths(path); + if (paths != null && ! paths.isEmpty()) { + h.addRelativeFiles(paths); + } else { + h.addRelativePaths(path); + h.addParameters("--sparse"); + } final VcsException[] exc = new VcsException[1]; final Semaphore semaphore = new Semaphore(); @@ -609,7 +614,7 @@ public class GitHistoryUtils { public static void hashesWithParents(Project project, FilePath path, final AsynchConsumer consumer, final Getter isCanceled, - final String... parameters) throws VcsException { + Collection paths, final String... parameters) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); @@ -619,10 +624,15 @@ public class GitHistoryUtils { h.setNoSSH(true); h.setStdoutSuppressed(true); h.addParameters(parameters); - h.addParameters(parser.getPretty(), "--encoding=UTF-8", "--full-history", "--sparse"); + h.addParameters(parser.getPretty(), "--encoding=UTF-8", "--full-history"); h.endOptions(); - h.addRelativePaths(path); + if (paths != null && ! paths.isEmpty()) { + h.addRelativeFiles(paths); + } else { + h.addParameters("--sparse"); + h.addRelativePaths(path); + } final Semaphore semaphore = new Semaphore(); h.addLineListener(new GitLineHandlerListener() { diff --git a/plugins/git4idea/src/git4idea/history/browser/ChangesFilter.java b/plugins/git4idea/src/git4idea/history/browser/ChangesFilter.java index 93c97a148ab4..d7903c386f19 100644 --- a/plugins/git4idea/src/git4idea/history/browser/ChangesFilter.java +++ b/plugins/git4idea/src/git4idea/history/browser/ChangesFilter.java @@ -19,9 +19,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.AreaMap; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.changes.FilePathsHelper; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.ArrayUtil; import com.intellij.util.PairProcessor; import git4idea.GitUtil; import org.jetbrains.annotations.NotNull; @@ -32,21 +30,13 @@ import java.util.regex.Pattern; public class ChangesFilter { - public static void filtersToParameters(Collection filters, List parameters) { + public static void filtersToParameters(Collection filters, List parameters, Collection paths) { for (Filter filter : filters) { filter.getCommandParametersFilter().applyToCommandLine(parameters); + filter.getCommandParametersFilter().applyToPaths(paths); } } - public static String[] filtersToParameterArray(Collection filters) { - if (filters == null || filters.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY; - final ArrayList strings = new ArrayList(); - for (Filter filter : filters) { - filter.getCommandParametersFilter().applyToCommandLine(strings); - } - return ArrayUtil.toStringArray(strings); - } - public abstract static class Merger { private final Collection myFilters; private MemoryFilter myResult; @@ -141,6 +131,7 @@ public class ChangesFilter { public interface CommandParametersFilter { void applyToCommandLine(final List sink); + void applyToPaths(Collection paths); } public interface Filter { @@ -163,6 +154,10 @@ public class ChangesFilter { public void applyToCommandLine(List sink) { sink.add("--author=" + myRegexp); } + + @Override + public void applyToPaths(Collection paths) { + } }; myMemoryFilter = new MemoryFilter() { public boolean applyInMemory(GitCommit commit) { @@ -211,6 +206,10 @@ public class ChangesFilter { public void applyToCommandLine(List sink) { sink.add("--committer=" + myRegexp); } + + @Override + public void applyToPaths(Collection paths) { + } }; myMemoryFilter = new MemoryFilter() { public boolean applyInMemory(GitCommit commit) { @@ -257,6 +256,10 @@ public class ChangesFilter { public void applyToCommandLine(List sink) { sink.add("--before=" + formatDate(myDate)); } + + @Override + public void applyToPaths(Collection paths) { + } }; myMemoryFilter = new MemoryFilter() { public boolean applyInMemory(GitCommit commit) { @@ -303,6 +306,10 @@ public class ChangesFilter { public void applyToCommandLine(List sink) { sink.add("--after=" + formatDate(myDate)); } + + @Override + public void applyToPaths(Collection paths) { + } }; myMemoryFilter = new MemoryFilter() { public boolean applyInMemory(GitCommit commit) { @@ -374,8 +381,13 @@ public class ChangesFilter { }; } - // todo optimization here - public boolean addPath(final VirtualFile vf) { + public void addFiles(final Collection files) { + for (VirtualFile file : files) { + myMap.put(FilePathsHelper.convertWithLastSeparator(file), file); + } + } + + /*public boolean addPath(final VirtualFile vf) { final Collection filesWeAlreadyHave = myMap.values(); final Collection childrenToRemove = new ArrayList(); for (VirtualFile current : filesWeAlreadyHave) { @@ -396,7 +408,7 @@ public class ChangesFilter { myMap.put(FilePathsHelper.convertWithLastSeparator(vf), vf); return true; - } + } */ public boolean containsFile(final VirtualFile vf) { return myMap.contains(FilePathsHelper.convertWithLastSeparator(vf)); @@ -412,7 +424,16 @@ public class ChangesFilter { // can be applied only in memory public CommandParametersFilter getCommandParametersFilter() { - return null; + return new CommandParametersFilter() { + @Override + public void applyToCommandLine(List sink) { + } + + @Override + public void applyToPaths(Collection paths) { + paths.addAll(myMap.values()); + } + }; } @NotNull @@ -435,6 +456,10 @@ public class ChangesFilter { sink.add("--grep=" + myRegexp); sink.add("--regexp-ignore-case"); } + + @Override + public void applyToPaths(Collection paths) { + } }; myMemoryFilter = new MemoryFilter() { public boolean applyInMemory(GitCommit commit) { diff --git a/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java b/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java index 68d13be93f67..f4e046aa785e 100644 --- a/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java +++ b/plugins/git4idea/src/git4idea/history/browser/LowLevelAccessImpl.java @@ -67,7 +67,8 @@ public class LowLevelAccessImpl implements LowLevelAccess { final AsynchConsumer consumer, Getter isCanceled, int useMaxCnt) throws VcsException { final List parameters = new ArrayList(); - ChangesFilter.filtersToParameters(filters, parameters); + final Collection paths = new HashSet(); + ChangesFilter.filtersToParameters(filters, parameters, paths); if (! startingPoints.isEmpty()) { for (String startingPoint : startingPoints) { @@ -80,7 +81,7 @@ public class LowLevelAccessImpl implements LowLevelAccess { parameters.add("--max-count=" + useMaxCnt); } - GitHistoryUtils.hashesWithParents(myProject, new FilePathImpl(myRoot), consumer, isCanceled, ArrayUtil.toStringArray(parameters)); + GitHistoryUtils.hashesWithParents(myProject, new FilePathImpl(myRoot), consumer, isCanceled, paths, ArrayUtil.toStringArray(parameters)); } @Override @@ -143,7 +144,8 @@ public class LowLevelAccessImpl implements LowLevelAccess { parameters.add("--max-count=" + useMaxCnt); } - ChangesFilter.filtersToParameters(filters, parameters); + final Collection paths = new HashSet(); + ChangesFilter.filtersToParameters(filters, parameters, paths); if (! startingPoints.isEmpty()) { for (String startingPoint : startingPoints) { @@ -158,7 +160,7 @@ public class LowLevelAccessImpl implements LowLevelAccess { } GitHistoryUtils.historyWithLinks(myProject, new FilePathImpl(myRoot), - refs, consumer, isCanceled, ArrayUtil.toStringArray(parameters)); + refs, consumer, isCanceled, paths, ArrayUtil.toStringArray(parameters)); } public List getBranchesWithCommit(final SHAHash hash) throws VcsException { diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/ByRootLoader.java b/plugins/git4idea/src/git4idea/history/wholeTree/ByRootLoader.java index e1da5bff25e1..31fb1d7d6341 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/ByRootLoader.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/ByRootLoader.java @@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.continuation.ContinuationContext; import com.intellij.util.continuation.TaskDescriptor; @@ -100,8 +101,11 @@ public class ByRootLoader extends TaskDescriptor { public void consume(List filters) { ProgressManager.checkCanceled(); try { + final List parameters = new ArrayList(); + final List paths = new ArrayList(); + ChangesFilter.filtersToParameters(filters, parameters, paths); final List> stash = GitHistoryUtils.loadStashStackAsCommits(myProject, myRootHolder.getRoot(), - mySymbolicRefs, ChangesFilter.filtersToParameterArray(filters)); + mySymbolicRefs, parameters.toArray(new String[parameters.size()])); if (stash == null) return; for (Pair pair : stash) { ProgressManager.checkCanceled(); @@ -120,7 +124,7 @@ public class ByRootLoader extends TaskDescriptor { myMediator.acceptException(e); } } - }, true); + }, true, myRootHolder.getRoot()); myDetailsCache.putStash(myRootHolder.getRoot(), stashMap); ProgressManager.checkCanceled(); @@ -141,7 +145,11 @@ public class ByRootLoader extends TaskDescriptor { public void consume(List filters) { for (String hash : hashes) { try { - final SHAHash shaHash = GitChangeUtils.commitExists(myProject, myRootHolder.getRoot(), hash, ChangesFilter.filtersToParameterArray(filters)); + final List parameters = new ArrayList(); + final List paths = new ArrayList(); + ChangesFilter.filtersToParameters(filters, parameters, paths); + final SHAHash shaHash = GitChangeUtils.commitExists(myProject, myRootHolder.getRoot(), hash, paths, + parameters.toArray(new String[parameters.size()])); if (shaHash == null) continue; if (controlSet.contains(shaHash)) continue; controlSet.add(shaHash); @@ -167,7 +175,7 @@ public class ByRootLoader extends TaskDescriptor { } } } - }, false); + }, false, myRootHolder.getRoot()); if (! result.isEmpty()) { final StepType stepType = myMediator.appendResult(myTicket, result, null); diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogFilters.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogFilters.java index 639386002470..16d42dda46f8 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogFilters.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogFilters.java @@ -16,14 +16,12 @@ package git4idea.history.wholeTree; import com.google.common.collect.Sets; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import git4idea.history.browser.ChangesFilter; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author irengrig @@ -36,7 +34,7 @@ public class GitLogFilters { @Nullable private final Set myCommitterFilters; @Nullable - private final Set myStructureFilters; + private final Map myStructureFilters; @Nullable private final List myPossibleReferencies; @@ -46,14 +44,14 @@ public class GitLogFilters { public GitLogFilters(@Nullable ChangesFilter.Comment commentFilter, @Nullable Set committerFilters, - @Nullable Set structureFilters, @Nullable List possibleReferencies) { + @Nullable Map structureFilters, @Nullable List possibleReferencies) { myCommentFilter = commentFilter; myCommitterFilters = committerFilters; myStructureFilters = structureFilters; myPossibleReferencies = possibleReferencies; } - public void callConsumer(final Consumer> consumer, boolean takeComment) { + public void callConsumer(final Consumer> consumer, boolean takeComment, final VirtualFile root) { final List> filters = new ArrayList>(); if (takeComment && myCommentFilter != null) { filters.add(Collections.singletonMap(myCommentFilter, myCommentFilter).keySet()); @@ -62,7 +60,10 @@ public class GitLogFilters { filters.add(myCommitterFilters); } if (myStructureFilters != null) { - filters.add(myStructureFilters); + final ChangesFilter.Filter filter = myStructureFilters.get(root); + if (filter != null) { + filters.add(Collections.singleton(filter)); + } } final Set> cartesian = Sets.cartesianProduct(filters); if (cartesian.isEmpty()) { @@ -85,7 +86,7 @@ public class GitLogFilters { } @Nullable - public Set getStructureFilters() { + public Map getStructureFilters() { return myStructureFilters; } @@ -98,4 +99,12 @@ public class GitLogFilters { public List getPossibleReferencies() { return myPossibleReferencies; } + + public boolean haveStructureFilter() { + return myStructureFilters != null; + } + + public boolean haveStructuresForRoot(VirtualFile root) { + return haveStructureFilter() && myStructureFilters.containsKey(root); + } } diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java index c9946bd0bace..689f24368453 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitLogUI.java @@ -17,6 +17,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; @@ -36,6 +37,7 @@ import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer; import com.intellij.openapi.vcs.changes.issueLinks.TableLinkMouseListener; import com.intellij.openapi.vcs.ui.SearchFieldAction; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; +import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.PopupHandler; @@ -45,6 +47,7 @@ import com.intellij.ui.table.JBTable; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; import com.intellij.util.Processor; +import com.intellij.util.SmartList; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; import com.intellij.util.text.DateFormatUtil; @@ -107,6 +110,8 @@ public class GitLogUI implements Disposable { private MyFilterUi myUserFilterI; private MyCherryPick myCherryPickAction; private MyRefreshAction myRefreshAction; + private MyStructureFilter myStructureFilter; + private StructureFilterAction myStructureFilterAction; private AnAction myCopyHashAction; // todo group somewhere?? private Consumer myDetailsLoaderImpl; @@ -603,6 +608,7 @@ public class GitLogUI implements Disposable { } group.add(myBranchSelectorAction.asTextAction()); group.add(myUsersFilterAction.asTextAction()); + group.add(myStructureFilterAction.asTextAction()); group.add(myCherryPickAction); group.add(ActionManager.getInstance().getAction("ChangesView.CreatePatchFromChanges")); group.add(myRefreshAction); @@ -618,16 +624,20 @@ public class GitLogUI implements Disposable { reloadRequest(); } }); - myUserFilterI = new MyFilterUi(new Runnable() { + final Runnable reloadCallback = new Runnable() { @Override public void run() { reloadRequest(); } - }); + }; + myUserFilterI = new MyFilterUi(reloadCallback); myUsersFilterAction = new UsersFilterAction(myProject, myUserFilterI); group.add(new MyTextFieldAction()); group.add(myBranchSelectorAction); group.add(myUsersFilterAction); + myStructureFilter = new MyStructureFilter(reloadCallback); + myStructureFilterAction = new StructureFilterAction(myProject, myStructureFilter); + group.add(myStructureFilterAction); myCherryPickAction = new MyCherryPick(); group.add(myCherryPickAction); group.add(ActionManager.getInstance().getAction("ChangesView.CreatePatchFromChanges")); @@ -1118,7 +1128,7 @@ public class GitLogUI implements Disposable { myCommentSearchContext.clear(); myUsersSearchContext.clear(); - if (commentFilterEmpty && (myUserFilterI.myFilter == null)) { + if (commentFilterEmpty && (myUserFilterI.myFilter == null) && myStructureFilter.myAllSelected) { myUsersSearchContext.clear(); myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, new GitLogFilters()); } else { @@ -1140,9 +1150,33 @@ public class GitLogUI implements Disposable { userFilters.add(new ChangesFilter.Author(regexp)); } } + Map structureFilters = null; + if (! myStructureFilter.myAllSelected) { + structureFilters = new HashMap(); + final Collection selected = new ArrayList(myStructureFilter.getSelected()); + final ArrayList copy = new ArrayList(myRootsUnderVcs); + Collections.sort(copy, FilePathComparator.getInstance()); + Collections.reverse(copy); + for (VirtualFile root : copy) { + final Collection selectedForRoot = new SmartList(); + final Iterator iterator = selected.iterator(); + while (iterator.hasNext()) { + VirtualFile next = iterator.next(); + if (VfsUtil.isAncestor(root, next, false)) { + selectedForRoot.add(next); + iterator.remove(); + } + } + if (! selectedForRoot.isEmpty()) { + final ChangesFilter.StructureFilter structureFilter = new ChangesFilter.StructureFilter(); + structureFilter.addFiles(selectedForRoot); + structureFilters.put(root, structureFilter); + } + } + } final List possibleReferencies = commentFilterEmpty ? null : Arrays.asList(myPreviousFilter.split("[\\s]")); - myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, new GitLogFilters(comment, userFilters, null, + myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, new GitLogFilters(comment, userFilters, structureFilters, possibleReferencies)); } myCommentSearchContext.addHighlighter(myDetailsPanel.getHtmlHighlighter()); @@ -1302,4 +1336,37 @@ public class GitLogUI implements Disposable { myMe = me == null ? "" : me.trim(); } } + + private static class MyStructureFilter implements StructureFilterI { + private boolean myAllSelected; + private final List myFiles; + private final Runnable myReloadCallback; + + private MyStructureFilter(Runnable reloadCallback) { + myReloadCallback = reloadCallback; + myFiles = new ArrayList(); + myAllSelected = true; + } + + @Override + public void allSelected() { + if (myAllSelected) return; + myAllSelected = true; + myReloadCallback.run(); + } + + @Override + public void select(Collection files) { + myAllSelected = false; + if (Comparing.haveEqualElements(files, myFiles)) return; + myFiles.clear(); + myFiles.addAll(files); + myReloadCallback.run(); + } + + @Override + public Collection getSelected() { + return myFiles; + } + } } diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java b/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java index b8589c22912d..edaec7fa2d80 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/LoadController.java @@ -65,15 +65,21 @@ public class LoadController implements Loader { new LoaderAndRefresherImpl.OneRootHolder(root) : new LoaderAndRefresherImpl.ManyCaseHolder(i, rootsHolder); + final boolean haveStructureFilter = filters.haveStructureFilter(); + // check if no files under root are selected + if (haveStructureFilter && ! filters.haveStructuresForRoot(root)) { + ++ i; + continue; + } filters.callConsumer(new Consumer>() { @Override public void consume(final List filters) { final LoaderAndRefresherImpl loaderAndRefresher = new LoaderAndRefresherImpl(ticket, filters, myMediator, startingPoints, myDetailsCache, myProject, rootHolder, myUsersIndex, - loadGrowthController.getId()); + loadGrowthController.getId(), haveStructureFilter); list.add(loaderAndRefresher); } - }, true); + }, true, root); shortLoaders.add(new ByRootLoader(myProject, rootHolder, myMediator, myDetailsCache, ticket, myUsersIndex, filters, startingPoints)); ++ i; diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresher.java b/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresher.java index 608360b93d5b..35be53b3c2be 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresher.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresher.java @@ -12,13 +12,10 @@ */ package git4idea.history.wholeTree; -import java.util.List; - /** * @author irengrig */ public interface LoaderAndRefresher { - void loadByHashesAside(final List hashes); LoadAlgorithm.Result load(final LoadAlgorithm.LoadType loadType, long continuation); StepType flushIntoUI(); void interrupt(); diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresherImpl.java b/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresherImpl.java index 5328e7b5525b..dbb78f9e0a44 100644 --- a/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresherImpl.java +++ b/plugins/git4idea/src/git4idea/history/wholeTree/LoaderAndRefresherImpl.java @@ -23,8 +23,10 @@ import com.intellij.util.BufferedListConsumer; import com.intellij.util.Consumer; import com.intellij.util.containers.Convertor; import git4idea.GitBranch; -import git4idea.changes.GitChangeUtils; -import git4idea.history.browser.*; +import git4idea.history.browser.ChangesFilter; +import git4idea.history.browser.GitCommit; +import git4idea.history.browser.LowLevelAccessImpl; +import git4idea.history.browser.SymbolicRefs; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -53,6 +55,7 @@ public class LoaderAndRefresherImpl implements LoaderAndRefresher hashes) { - final List result = new ArrayList(); - final List> parents = myLoadParents ? new ArrayList>() : null; - for (String hash : hashes) { - try { - final SHAHash shaHash = GitChangeUtils.commitExists(myProject, myRootHolder.getRoot(), hash); - if (shaHash == null) continue; - final List commits = myLowLevelAccess.getCommitDetails(Collections.singletonList(shaHash.getValue()), mySymbolicRefs); - myDetailsCache.acceptAnswer(commits, myRootHolder.getRoot()); - appendCommits(result, parents, commits); - } - catch (VcsException e1) { - continue; - } - } - if (! result.isEmpty()) { - final StepType stepType = myMediator.appendResult(myTicket, result, parents); - // here we react only on "stop", not on "pause" - if (StepType.STOP.equals(stepType)) { - myStepType = StepType.STOP; - } - } - } - private void appendCommits(List result, List> parents, List commits) { for (GitCommit commit : commits) { final Commit commitObj = diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java new file mode 100644 index 000000000000..93cb37c90c22 --- /dev/null +++ b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterAction.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git4idea.history.wholeTree; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Consumer; +import git4idea.GitVcs; + +import java.util.Collection; +import java.util.Map; + +/** + * @author irengrig + * Date: 2/3/11 + * Time: 4:29 PM + */ +public class StructureFilterAction extends BasePopupAction { + public static final String ALL = "All"; + public static final String STRUCTURE = "Structure:"; + public static final String FILTER = "(filter)"; + private final DumbAwareAction myAll; + private final DumbAwareAction mySelect; + private final StructureFilterI myStructureFilterI; + + public StructureFilterAction(Project project, final StructureFilterI structureFilterI) { + super(project, STRUCTURE, "Structure"); + myStructureFilterI = structureFilterI; + myAll = new DumbAwareAction(ALL) { + @Override + public void actionPerformed(AnActionEvent e) { + myLabel.setText(ALL); + myPanel.setToolTipText(STRUCTURE + " " + ALL); + structureFilterI.allSelected(); + } + }; + mySelect = new DumbAwareAction("Select...") { + @Override + public void actionPerformed(AnActionEvent e) { + final VcsStructureChooser vcsStructureChooser = + new VcsStructureChooser(GitVcs.getInstance(myProject), "Select folders to filter by", structureFilterI.getSelected()); + vcsStructureChooser.show(); + if (vcsStructureChooser.getExitCode() == DialogWrapper.CANCEL_EXIT_CODE) return; + final Collection files = vcsStructureChooser.getSelectedFiles(); + final Map modulesSet = vcsStructureChooser.getModulesSet(); + String text; + if (files.size() == 1) { + final VirtualFile file = files.iterator().next(); + final String module = modulesSet.get(file); + text = module == null ? file.getName() : module; + } + else { + text = FILTER; + } + text = text.length() > 20 ? FILTER : text; + myLabel.setText(text); + + final String toolTip; + final StringBuilder sb = new StringBuilder(); + for (VirtualFile file : files) { + sb.append("
"); + final String module = modulesSet.get(file); + final String name = module == null ? file.getName() : module; + sb.append(name).append(" (").append(file.getPath()).append(")"); + } + toolTip = sb.toString(); + myPanel.setToolTipText("" + STRUCTURE + "
" + toolTip + ""); + structureFilterI.select(files); + } + }; + myLabel.setText(ALL); + } + + @Override + protected void createActions(Consumer actionConsumer) { + actionConsumer.consume(myAll); + actionConsumer.consume(mySelect); + } +} diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterI.java b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterI.java new file mode 100644 index 000000000000..1a2dd4a2d8e0 --- /dev/null +++ b/plugins/git4idea/src/git4idea/history/wholeTree/StructureFilterI.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git4idea.history.wholeTree; + +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; + +/** + * @author irengrig + * Date: 7/8/11 + * Time: 1:49 PM + */ +public interface StructureFilterI { + void allSelected(); + void select(final Collection files); + Collection getSelected(); +} diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java b/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java new file mode 100644 index 000000000000..f3cc9fccc6e5 --- /dev/null +++ b/plugins/git4idea/src/git4idea/history/wholeTree/VcsStructureChooser.java @@ -0,0 +1,457 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git4idea.history.wholeTree; + +import com.intellij.ide.util.treeView.AbstractTreeUi; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor; +import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.changes.ui.VirtualFileListCellRenderer; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.*; +import com.intellij.ui.components.JBList; +import com.intellij.ui.components.JBScrollPane; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.PlatformIcons; +import com.intellij.util.PlusMinus; +import com.intellij.util.TreeNodeState; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.hash.HashSet; +import com.intellij.util.treeWithCheckedNodes.SelectionManager; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.*; + +/** + * @author irengrig + * Date: 2/3/11 + * Time: 12:04 PM + */ +public class VcsStructureChooser extends DialogWrapper { + private final static int MAX_FOLDERS = 10; + public static final Border BORDER = IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.LEFT); + public static final String DEFAULT_TEXT = "Selected:"; + public static final String CAN_NOT_ADD_TEXT = "Selected: (You have added " + MAX_FOLDERS + " elements. No more is allowed.)"; + private final AbstractVcs myVcs; + private Set myRoots; + private Map myModulesSet; + private SelectionManager mySelectionManager; + private DefaultMutableTreeNode myRoot; + private JBList mySelectedList; + private JLabel mySelectedLabel; + private Tree myTree; + + public VcsStructureChooser(final AbstractVcs vcs, final String title, final Collection initialSelection) { + super(vcs.getProject(), true); + setTitle(title); + myVcs = vcs; + mySelectionManager = new SelectionManager(MAX_FOLDERS, 500, MyNodeConvertor.getInstance()); + init(); + mySelectionManager.setSelection(initialSelection); + checkEmptyness(); + } + + // todo background? + private void calculateRoots() { + final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myVcs.getProject()); + final VirtualFile[] rootsUnderVcs = vcsManager.getRootsUnderVcs(myVcs); + + final ModuleManager moduleManager = ModuleManager.getInstance(myVcs.getProject()); + // assertion for read access inside + final Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable() { + public Module[] compute() { + return moduleManager.getModules(); + } + }); + + myRoots = new HashSet(); + myRoots.addAll(Arrays.asList(rootsUnderVcs)); + myModulesSet = new HashMap(); + for (Module module : modules) { + final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots(); + for (VirtualFile file : files) { + if (myVcs.equals(vcsManager.getVcsFor(file))) { + myModulesSet.put(file, module.getName()); + myRoots.add(file); + } + } + } + } + + public Map getModulesSet() { + return myModulesSet; + } + + public Collection getSelectedFiles() { + return ((CollectionListModel) mySelectedList.getModel()).getItems(); + } + + private void checkEmptyness() { + setOKActionEnabled(mySelectedList.getModel().getSize() > 0); + } + + @Override + protected String getDimensionServiceKey() { + return "git4idea.history.wholeTree.VcsStructureChooser"; + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myTree; + } + + @Override + protected JComponent createCenterPanel() { + final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, true, false, true); + calculateRoots(); + final ArrayList list = new ArrayList(myRoots); + final Comparator comparator = new Comparator() { + @Override + public int compare(VirtualFile o1, VirtualFile o2) { + final String module1 = myModulesSet.get(o1); + final String path1 = module1 != null ? module1 : o1.getPath(); + final String module2 = myModulesSet.get(o2); + final String path2 = module2 != null ? module2 : o2.getPath(); + return path1.compareToIgnoreCase(path2); + } + }; + for (VirtualFile root : list) { + descriptor.addRoot(root); + } + myTree = new Tree(); + myTree.setMinimumSize(new Dimension(200, 200)); + myTree.setBorder(BORDER); + myTree.setShowsRootHandles(true); + myTree.setRootVisible(true); + final MyCheckboxTreeCellRenderer cellRenderer = new MyCheckboxTreeCellRenderer(mySelectionManager, myModulesSet, myVcs.getProject(), + myTree, myRoots); + final FileSystemTreeImpl fileSystemTree = new FileSystemTreeImpl(myVcs.getProject(), descriptor, myTree, cellRenderer, null, new Convertor() { + @Override + public String convert(TreePath o) { + final DefaultMutableTreeNode lastPathComponent = ((DefaultMutableTreeNode) o.getLastPathComponent()); + final Object uo = lastPathComponent.getUserObject(); + if (uo instanceof FileNodeDescriptor) { + final VirtualFile file = ((FileNodeDescriptor)uo).getElement().getFile(); + final String module = myModulesSet.get(file); + if (module != null) return module; + return file == null ? "" : file.getName(); + } + return o.toString(); + } + }); + final AbstractTreeUi ui = fileSystemTree.getTreeBuilder().getUi(); + ui.setNodeDescriptorComparator(new Comparator() { + @Override + public int compare(NodeDescriptor o1, NodeDescriptor o2) { + if (o1 instanceof FileNodeDescriptor && o2 instanceof FileNodeDescriptor) { + final VirtualFile f1 = ((FileNodeDescriptor)o1).getElement().getFile(); + final VirtualFile f2 = ((FileNodeDescriptor)o2).getElement().getFile(); + return comparator.compare(f1, f2); + } + return o1.getIndex() - o2.getIndex(); + } + }); + myRoot = (DefaultMutableTreeNode)myTree.getModel().getRoot(); + + myTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + int row = myTree.getRowForLocation(e.getX(), e.getY()); + if (row < 0) return; + final Object o = myTree.getPathForRow(row).getLastPathComponent(); + if (myRoot == o || getFile(o) == null) return; + + Rectangle rowBounds = myTree.getRowBounds(row); + cellRenderer.setBounds(rowBounds); + Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); + checkBounds.setLocation(rowBounds.getLocation()); + + if (checkBounds.height == 0) checkBounds.height = rowBounds.height; + + if (checkBounds.contains(e.getPoint())) { + mySelectionManager.toggleSelection((DefaultMutableTreeNode)o); + myTree.revalidate(); + myTree.repaint(); + e.consume(); + } + } + }); + + myTree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + TreePath treePath = myTree.getLeadSelectionPath(); + if (treePath == null) return; + final Object o = treePath.getLastPathComponent(); + if (myRoot == o || getFile(o) == null) return; + mySelectionManager.toggleSelection((DefaultMutableTreeNode)o); + myTree.revalidate(); + myTree.repaint(); + e.consume(); + } + } + }); + + final Splitter splitter = new Splitter(true, 0.7f); + splitter.setFirstComponent(new JBScrollPane(fileSystemTree.getTree())); + final JPanel wrapper = new JPanel(new BorderLayout()); + mySelectedLabel = new JLabel(DEFAULT_TEXT); + mySelectedLabel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); + wrapper.add(mySelectedLabel, BorderLayout.NORTH); + mySelectedList = new JBList(new CollectionListModel(new ArrayList())); + mySelectedList.setCellRenderer(new WithModulesListCellRenderer(myVcs.getProject(), myModulesSet)); + wrapper.add(ScrollPaneFactory.createScrollPane(mySelectedList), BorderLayout.CENTER); + splitter.setSecondComponent(wrapper); + + mySelectionManager.setSelectionChangeListener(new PlusMinus() { + @Override + public void plus(VirtualFile virtualFile) { + final CollectionListModel model = (CollectionListModel)mySelectedList.getModel(); + model.add(virtualFile); + model.sort(FilePathComparator.getInstance()); + recalculateErrorText(); + mySelectedList.revalidate(); + mySelectedList.repaint(); + } + + private void recalculateErrorText() { + checkEmptyness(); + if (mySelectionManager.canAddSelection()) { + mySelectedLabel.setText(DEFAULT_TEXT); + } else { + mySelectedLabel.setText(CAN_NOT_ADD_TEXT); + } + mySelectedLabel.revalidate(); + } + + @Override + public void minus(VirtualFile virtualFile) { + final CollectionListModel defaultListModel = (CollectionListModel)mySelectedList.getModel(); + for (int i = 0; i < defaultListModel.getSize(); i++) { + final VirtualFile elementAt = (VirtualFile)defaultListModel.getElementAt(i); + if (virtualFile.equals(elementAt)) { + defaultListModel.remove(i); + break; + } + } + defaultListModel.sort(FilePathComparator.getInstance()); + recalculateErrorText(); + mySelectedList.revalidate(); + mySelectedList.repaint(); + } + }); + mySelectedList.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_DELETE) { + final int[] idx = mySelectedList.getSelectedIndices(); + if (idx != null && idx.length > 0) { + final int answer = Messages + .showYesNoDialog(myVcs.getProject(), "Remove selected paths from filter?", "Remove from filter", Messages.getQuestionIcon()); + if (Messages.OK == answer) { + Arrays.sort(idx); + for (int i = idx.length - 1; i >= 0; --i) { + int i1 = idx[i]; + mySelectionManager.removeSelection((VirtualFile)((CollectionListModel) mySelectedList.getModel()).getElementAt(i1)); + myTree.revalidate(); + myTree.repaint(); + } + } + } + } + } + }); + + return splitter; + } + + @Nullable + private static VirtualFile getFile(final Object node) { + if (! (((DefaultMutableTreeNode)node).getUserObject() instanceof FileNodeDescriptor)) return null; + final FileNodeDescriptor descriptor = (FileNodeDescriptor)((DefaultMutableTreeNode)node).getUserObject(); + if (descriptor.getElement().getFile() == null) return null; + return descriptor.getElement().getFile(); + } + + private static class MyCheckboxTreeCellRenderer extends JPanel implements TreeCellRenderer { + private final WithModulesListCellRenderer myTextRenderer; + public final JCheckBox myCheckbox; + private final SelectionManager mySelectionManager; + private final Map myModulesSet; + private final Collection myRoots; + private final ColoredTreeCellRenderer myColoredRenderer; + private final JLabel myEmpty; + private final JList myFictive; + + private MyCheckboxTreeCellRenderer(final SelectionManager selectionManager, Map modulesSet, final Project project, + final JTree tree, final Collection roots) { + super(new BorderLayout()); + mySelectionManager = selectionManager; + myModulesSet = modulesSet; + myRoots = roots; + myColoredRenderer = new ColoredTreeCellRenderer() { + @Override + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + append(value.toString()); + } + }; + myFictive = new JBList(); + myFictive.setBackground(tree.getBackground()); + myFictive.setSelectionBackground(UIUtil.getListSelectionBackground()); + myFictive.setSelectionForeground(UIUtil.getListSelectionForeground()); + + myTextRenderer = new WithModulesListCellRenderer(project, myModulesSet) { + @Override + protected void putParentPath(Object value, FilePath path, FilePath self) { + if (myRoots.contains(self.getVirtualFile())) { + super.putParentPath(value, path, self); + } + } + }; + + myCheckbox = new JCheckBox(); + myEmpty = new JLabel(""); + + add(myCheckbox, BorderLayout.WEST); + add(myTextRenderer, BorderLayout.CENTER); + myCheckbox.setVisible(true); + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + myTextRenderer.setOpened(expanded); + invalidate(); + final VirtualFile file = getFile(value); + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + if (file == null) { + if (value instanceof DefaultMutableTreeNode) { + final Object uo = node.getUserObject(); + if (uo instanceof String) { + myColoredRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + return myColoredRenderer; + } + } + return myEmpty; + } + myCheckbox.setVisible(true); + final TreeNodeState state = mySelectionManager.getState(node); + myCheckbox.setEnabled(TreeNodeState.CLEAR.equals(state) || TreeNodeState.SELECTED.equals(state)); + myCheckbox.setSelected(!TreeNodeState.CLEAR.equals(state)); + myTextRenderer.getListCellRendererComponent(myFictive, file, 0, selected, hasFocus); + revalidate(); + return this; + } + } + + private static class MyNodeConvertor implements Convertor { + private final static MyNodeConvertor ourInstance = new MyNodeConvertor(); + + public static MyNodeConvertor getInstance() { + return ourInstance; + } + + @Override + public VirtualFile convert(DefaultMutableTreeNode o) { + return ((FileNodeDescriptor)o.getUserObject()).getElement().getFile(); + } + } + + private static class WithModulesListCellRenderer extends VirtualFileListCellRenderer { + private boolean opened; + private final Map myModules; + + private WithModulesListCellRenderer(Project project, final Map modules) { + super(project, true); + myModules = modules; + } + + public void setOpened(boolean opened) { + this.opened = opened; + } + + @Override + protected String getName(FilePath path) { + final String module = myModules.get(path.getVirtualFile()); + if (module != null) { + return module; + } + return super.getName(path); + } + + @Override + protected void renderIcon(FilePath path) { + final String module = myModules.get(path.getVirtualFile()); + if (module != null) { + if (opened) { + setIcon(PlatformIcons.CONTENT_ROOT_ICON_OPEN); + } else { + setIcon(PlatformIcons.CONTENT_ROOT_ICON_CLOSED); + } + } else { + if (path.isDirectory()) { + if (opened) { + setIcon(PlatformIcons.DIRECTORY_OPEN_ICON); + } else { + setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON); + } + } else { + setIcon(path.getFileType().getIcon()); + } + } + } + + @Override + protected void putParentPathImpl(Object value, String parentPath, FilePath self) { + append(self.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES); + } + } +} diff --git a/plugins/git4idea/tests/git4idea/tests/GitHistoryUtilsTest.java b/plugins/git4idea/tests/git4idea/tests/GitHistoryUtilsTest.java index f47dd289b68b..e5db5bc01289 100644 --- a/plugins/git4idea/tests/git4idea/tests/GitHistoryUtilsTest.java +++ b/plugins/git4idea/tests/git4idea/tests/GitHistoryUtilsTest.java @@ -270,7 +270,7 @@ public class GitHistoryUtilsTest extends GitSingleUserTest { } }; - GitHistoryUtils.hashesWithParents(myProject, bfilePath, consumer, null); + GitHistoryUtils.hashesWithParents(myProject, bfilePath, consumer, null, null); assertEquals(hashesWithParents.size(), expectedSize); for (Iterator hit = hashesWithParents.iterator(), myIt = myRevisionsAfterRename.iterator(); hit.hasNext(); ) {