Move: Improved file chooser with search

#KT-9752 Fixed
This commit is contained in:
Alexey Sedunov
2016-01-25 16:21:54 +03:00
parent 625bfe12eb
commit 58963f7053
5 changed files with 104 additions and 15 deletions
@@ -35,9 +35,11 @@ fun Project.projectScope(): GlobalSearchScope = GlobalSearchScope.projectScope(t
fun PsiFile.fileScope(): GlobalSearchScope = GlobalSearchScope.fileScope(this)
fun GlobalSearchScope.restrictToKotlinSources() = GlobalSearchScope.getScopeRestrictedByFileTypes(this, KotlinFileType.INSTANCE)
fun SearchScope.restrictToKotlinSources(): SearchScope {
return when (this) {
is GlobalSearchScope -> GlobalSearchScope.getScopeRestrictedByFileTypes(this, KotlinFileType.INSTANCE)
is GlobalSearchScope -> restrictToKotlinSources()
is LocalSearchScope -> {
val ktElements = scope.filter { it.containingFile is KtFile }
when (ktElements.size) {
@@ -34,6 +34,10 @@ public class KtFileTreeNode extends PsiFileNode {
super(project, value, viewSettings);
}
public final KtFile getKtFile() {
return (KtFile) getValue();
}
@Override
public Collection<AbstractTreeNode> getChildrenImpl() {
KtFile file = (KtFile) getValue();
@@ -35,7 +35,6 @@ column.name.val.var=Val/Var
refactoring.move.specifc.element=Move {0} {1}
refactoring.move.selected.elements=Move selected elements
refactoring.move.top.level.declaration.file.title=Choose Destination File
refactoring.move.non.kotlin.file=Target must be a Kotlin file
package.private.0.will.no.longer.be.accessible.from.1=Package-private {0} will no longer be accessible from {1}
@@ -19,15 +19,11 @@ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JavaProjectRootsUtil;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pass;
@@ -70,6 +66,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPan
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable;
import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt;
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*;
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinFileChooserDialog;
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
@@ -139,8 +136,6 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
initMemberInfo(elementsToMove, sourceFiles);
updateControls();
pack();
}
private static List<KtFile> getSourceFiles(@NotNull Collection<KtNamedDeclaration> elementsToMove) {
@@ -337,12 +332,36 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
@NotNull Set<KtNamedDeclaration> elementsToMove,
@NotNull List<KtFile> sourceFiles
) {
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
.withRoots(ProjectRootManager.getInstance(myProject).getContentRoots())
.withTreeRootVisible(true);
final PsiDirectory sourceDir = sourceFiles.get(0).getParent();
assert sourceDir != null : sourceFiles.get(0).getVirtualFile().getPath();
String title = KotlinRefactoringBundle.message("refactoring.move.top.level.declaration.file.title");
fileChooser.addBrowseFolderListener(title, null, myProject, descriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
fileChooser.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
KotlinFileChooserDialog dialog = new KotlinFileChooserDialog("Choose Containing File", myProject);
File targetFile = new File(getTargetFilePath());
PsiFile targetPsiFile = JetRefactoringUtilKt.toPsiFile(targetFile, myProject);
if (targetPsiFile instanceof KtFile) {
dialog.select((KtFile) targetPsiFile);
}
else {
PsiDirectory targetDir = JetRefactoringUtilKt.toPsiDirectory(targetFile.getParentFile(), myProject);
if (targetDir == null) {
targetDir = sourceDir;
}
dialog.selectDirectory(targetDir);
}
dialog.showDialog();
KtFile selectedFile = dialog.isOK() ? dialog.getSelected() : null;
if (selectedFile != null) {
fileChooser.setText(selectedFile.getVirtualFile().getPath());
}
}
}
);
String initialTargetPath =
targetFile != null
@@ -561,8 +580,11 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
}
File targetDir = targetFile.getParentFile();
final PsiDirectory psiDirectory = JetRefactoringUtilKt.toPsiDirectory(targetDir, myProject);
assert psiDirectory != null : "No directory found: " + targetDir.getPath();
final PsiDirectory psiDirectory = targetDir != null ? JetRefactoringUtilKt.toPsiDirectory(targetDir, myProject) : null;
if (psiDirectory == null) {
setErrorText("No directory found for file: " + targetFile.getPath());
return null;
}
PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory);
if (psiPackage == null) {
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring.ui
import com.intellij.ide.util.AbstractTreeClassChooserDialog
import com.intellij.ide.util.gotoByName.GotoFileModel
import com.intellij.openapi.project.Project
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.projectView.KtClassOrObjectTreeNode
import org.jetbrains.kotlin.idea.projectView.KtFileTreeNode
import org.jetbrains.kotlin.idea.search.projectScope
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
import org.jetbrains.kotlin.psi.KtFile
import javax.swing.tree.DefaultMutableTreeNode
class KotlinFileChooserDialog(
title: String,
project: Project
) : AbstractTreeClassChooserDialog<KtFile>(
title,
project,
project.projectScope().restrictToKotlinSources(),
KtFile::class.java,
null,
null,
null,
false,
false
) {
override fun getSelectedFromTreeUserObject(node: DefaultMutableTreeNode): KtFile? {
val userObject = node.userObject
return when (userObject) {
is KtFileTreeNode -> userObject.ktFile
is KtClassOrObjectTreeNode -> {
val containingFile = userObject.value.getContainingKtFile()
if (containingFile.declarations.size == 1) containingFile else null
}
else -> null
}
}
override fun getClassesByName(name: String, checkBoxState: Boolean, pattern: String, searchScope: GlobalSearchScope): List<KtFile> {
return FilenameIndex.getFilesByName(project, name, searchScope).filterIsInstance<KtFile>()
}
override fun createChooseByNameModel() = GotoFileModel(this.project)
}