Move File: Reimplement Move dialog for Kotlin files. Do not show "Search for references" option (consider it true in all cases)
#KT-10118 Fixed
This commit is contained in:
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.move.moveTopLevelDeclarations.ui
|
||||
|
||||
import com.intellij.ide.util.DirectoryUtil
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.fileChooser.FileChooserFactory
|
||||
import com.intellij.openapi.help.HelpManager
|
||||
import com.intellij.openapi.keymap.KeymapUtil
|
||||
import com.intellij.openapi.project.DumbModePermission
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.ui.TextComponentAccessor
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.refactoring.RefactoringBundle
|
||||
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||
import com.intellij.ui.DocumentAdapter
|
||||
import com.intellij.ui.NonFocusableCheckBox
|
||||
import com.intellij.ui.RecentsManager
|
||||
import com.intellij.ui.TextFieldWithHistoryWithBrowseButton
|
||||
import com.intellij.ui.components.JBLabelDecorator
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.ui.FormBuilder
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectory
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot
|
||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.event.DocumentEvent
|
||||
|
||||
public class KotlinAwareMoveFilesOrDirectoriesDialog(
|
||||
private val project: Project,
|
||||
private val callback: (KotlinAwareMoveFilesOrDirectoriesDialog?) -> Unit
|
||||
) : DialogWrapper(project, true) {
|
||||
companion object {
|
||||
private val RECENT_KEYS = "MoveFile.RECENT_KEYS"
|
||||
private val MOVE_FILES_OPEN_IN_EDITOR = "MoveFile.OpenInEditor"
|
||||
}
|
||||
|
||||
private val nameLabel = JBLabelDecorator.createJBLabelDecorator().setBold(true)
|
||||
private val targetDirectoryField = TextFieldWithHistoryWithBrowseButton()
|
||||
private val openInEditorCb = NonFocusableCheckBox("Open moved files in editor")
|
||||
private val updatePackageDirectiveCb = NonFocusableCheckBox()
|
||||
|
||||
private var helpID: String? = null
|
||||
var targetDirectory: PsiDirectory? = null
|
||||
private set
|
||||
|
||||
init {
|
||||
title = RefactoringBundle.message("move.title")
|
||||
init()
|
||||
}
|
||||
|
||||
public val updatePackageDirective: Boolean
|
||||
get() = updatePackageDirectiveCb.isSelected
|
||||
|
||||
override fun createActions() = arrayOf(okAction, cancelAction, helpAction)
|
||||
|
||||
override fun getPreferredFocusedComponent() = targetDirectoryField.childComponent
|
||||
|
||||
override fun createCenterPanel() = null
|
||||
|
||||
override fun createNorthPanel(): JComponent {
|
||||
RecentsManager.getInstance(project).getRecentEntries(RECENT_KEYS)?.let { targetDirectoryField.childComponent.history = it }
|
||||
|
||||
val descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor()
|
||||
targetDirectoryField.addBrowseFolderListener(RefactoringBundle.message("select.target.directory"),
|
||||
RefactoringBundle.message("the.file.will.be.moved.to.this.directory"),
|
||||
project,
|
||||
descriptor,
|
||||
TextComponentAccessor.TEXT_FIELD_WITH_HISTORY_WHOLE_TEXT)
|
||||
val textField = targetDirectoryField.childComponent.textEditor
|
||||
FileChooserFactory.getInstance().installFileCompletion(textField, descriptor, true, disposable)
|
||||
textField.document.addDocumentListener(
|
||||
object : DocumentAdapter() {
|
||||
override fun textChanged(e: DocumentEvent) {
|
||||
validateOKButton()
|
||||
}
|
||||
}
|
||||
)
|
||||
targetDirectoryField.setTextFieldPreferredWidth(CopyFilesOrDirectoriesDialog.MAX_PATH_LENGTH)
|
||||
Disposer.register(disposable, targetDirectoryField)
|
||||
|
||||
openInEditorCb.isSelected = isOpenInEditor()
|
||||
|
||||
val shortcutText = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION))
|
||||
return FormBuilder.createFormBuilder()
|
||||
.addComponent(nameLabel)
|
||||
.addLabeledComponent(RefactoringBundle.message("move.files.to.directory.label"), targetDirectoryField, UIUtil.LARGE_VGAP)
|
||||
.addTooltip(RefactoringBundle.message("path.completion.shortcut", shortcutText))
|
||||
.addComponentToRightColumn(openInEditorCb, UIUtil.LARGE_VGAP)
|
||||
.addComponentToRightColumn(updatePackageDirectiveCb, UIUtil.LARGE_VGAP)
|
||||
.panel
|
||||
}
|
||||
|
||||
fun setData(psiElements: Array<out PsiElement>, initialTargetDirectory: PsiDirectory?, helpID: String) {
|
||||
val psiElement = psiElements.singleOrNull()
|
||||
if (psiElement != null) {
|
||||
val shortenedPath = CopyFilesOrDirectoriesDialog.shortenPath((psiElement as PsiFileSystemItem).virtualFile)
|
||||
nameLabel.text = when (psiElement) {
|
||||
is PsiFile -> RefactoringBundle.message("move.file.0", shortenedPath)
|
||||
else -> RefactoringBundle.message("move.directory.0", shortenedPath)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val isFile = psiElements.all { it is PsiFile }
|
||||
val isDirectory = psiElements.all { it is PsiDirectory }
|
||||
nameLabel.text = when {
|
||||
isFile -> RefactoringBundle.message("move.specified.files")
|
||||
isDirectory -> RefactoringBundle.message("move.specified.directories")
|
||||
else -> RefactoringBundle.message("move.specified.elements")
|
||||
}
|
||||
}
|
||||
|
||||
targetDirectoryField.childComponent.text = initialTargetDirectory?.virtualFile?.presentableUrl ?: ""
|
||||
|
||||
validateOKButton()
|
||||
this.helpID = helpID
|
||||
|
||||
with (updatePackageDirectiveCb) {
|
||||
val jetFiles = psiElements.filterIsInstance<KtFile>().filter { it.isInJavaSourceRoot() }
|
||||
if (jetFiles.isEmpty()) {
|
||||
parent.remove(updatePackageDirectiveCb)
|
||||
return
|
||||
}
|
||||
|
||||
val singleFile = jetFiles.singleOrNull()
|
||||
isSelected = singleFile == null || singleFile.packageMatchesDirectory()
|
||||
text = "Update package directive (Kotlin files)"
|
||||
}
|
||||
}
|
||||
|
||||
override fun doHelpAction() = HelpManager.getInstance().invokeHelp(helpID)
|
||||
|
||||
fun isOpenInEditor(): Boolean {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) return false
|
||||
return PropertiesComponent.getInstance().getBoolean(MOVE_FILES_OPEN_IN_EDITOR, true)
|
||||
}
|
||||
|
||||
private fun validateOKButton() {
|
||||
isOKActionEnabled = targetDirectoryField.childComponent.text.length > 0
|
||||
}
|
||||
|
||||
override fun doOKAction() {
|
||||
PropertiesComponent.getInstance().setValue(MOVE_FILES_OPEN_IN_EDITOR, openInEditorCb.isSelected, true)
|
||||
RecentsManager.getInstance(project).registerRecentEntry(RECENT_KEYS, targetDirectoryField.childComponent.text)
|
||||
|
||||
if (DumbService.isDumb(project)) {
|
||||
Messages.showMessageDialog(project, "Move refactoring is not available while indexing is in progress", "Indexing", null)
|
||||
return
|
||||
}
|
||||
|
||||
project.executeCommand(RefactoringBundle.message("move.title"), null) {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_MODAL) {
|
||||
runWriteAction {
|
||||
val directoryName = targetDirectoryField.childComponent.text.replace(File.separatorChar, '/')
|
||||
try {
|
||||
targetDirectory = DirectoryUtil.mkdirs(PsiManager.getInstance(project), directoryName)
|
||||
}
|
||||
catch (e: IncorrectOperationException) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (targetDirectory == null) {
|
||||
CommonRefactoringUtil.showErrorMessage(title,
|
||||
RefactoringBundle.message("cannot.create.directory"),
|
||||
helpID,
|
||||
project)
|
||||
return@allowStartingDumbModeInside
|
||||
}
|
||||
|
||||
callback(this@KotlinAwareMoveFilesOrDirectoriesDialog)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.move.moveTopLevelDeclarations.ui
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesDialog
|
||||
import com.intellij.ui.NonFocusableCheckBox
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectory
|
||||
import java.awt.GridBagConstraints
|
||||
import java.awt.Insets
|
||||
import javax.swing.JCheckBox
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
public class MoveFilesOrDirectoriesDialogWithKotlinOptions(
|
||||
project: Project,
|
||||
callback: (MoveFilesOrDirectoriesDialog?) -> Unit): MoveFilesOrDirectoriesDialog(project, callback) {
|
||||
private var cbUpdatePackageDirective: JCheckBox? = null
|
||||
|
||||
public val updatePackageDirective: Boolean
|
||||
get() = cbUpdatePackageDirective!!.isSelected()
|
||||
|
||||
override fun createNorthPanel(): JComponent {
|
||||
val panel = super.createNorthPanel()
|
||||
|
||||
val gbc = GridBagConstraints()
|
||||
|
||||
gbc.gridwidth = 1
|
||||
gbc.gridx = 0
|
||||
gbc.gridy = GridBagConstraints.RELATIVE
|
||||
gbc.weightx = 0.0
|
||||
gbc.weighty = 0.0
|
||||
gbc.fill = GridBagConstraints.NONE
|
||||
gbc.anchor = GridBagConstraints.WEST
|
||||
gbc.insets = Insets(UIUtil.LARGE_VGAP, 0, 0, UIUtil.DEFAULT_HGAP)
|
||||
panel!!.add(JLabel(), gbc)
|
||||
|
||||
cbUpdatePackageDirective = NonFocusableCheckBox()
|
||||
gbc.gridx = 1
|
||||
gbc.weightx = 1.0
|
||||
gbc.weighty = 0.0
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL
|
||||
gbc.anchor = GridBagConstraints.WEST
|
||||
gbc.insets = Insets(UIUtil.LARGE_VGAP, 0, 0, 0)
|
||||
panel.add(cbUpdatePackageDirective, gbc)
|
||||
|
||||
return panel
|
||||
}
|
||||
|
||||
override fun setData(psiElements: Array<out PsiElement>, initialTargetDirectory: PsiDirectory?, helpID: String) {
|
||||
super.setData(psiElements, initialTargetDirectory, helpID)
|
||||
|
||||
with (cbUpdatePackageDirective!!) {
|
||||
val jetFiles = psiElements.filterIsInstance<KtFile>().filter { it.isInJavaSourceRoot() }
|
||||
if (jetFiles.isEmpty()) {
|
||||
getParent().remove(cbUpdatePackageDirective)
|
||||
return
|
||||
}
|
||||
|
||||
val singleFile = jetFiles.singleOrNull()
|
||||
setSelected(singleFile == null || singleFile.packageMatchesDirectory())
|
||||
setText("Update package directive (Kotlin files)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import com.intellij.refactoring.RefactoringBundle
|
||||
import com.intellij.refactoring.RefactoringSettings
|
||||
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler
|
||||
import com.intellij.refactoring.move.MoveHandler
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesDialog
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||
import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions
|
||||
@@ -49,7 +48,7 @@ import org.jetbrains.kotlin.idea.codeInsight.KotlinFileReferencesResolver
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.isInJavaSourceRoot
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.isImported
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveFilesOrDirectoriesDialogWithKotlinOptions
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
|
||||
@@ -64,9 +63,7 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.Comparator
|
||||
import java.util.*
|
||||
|
||||
val UNKNOWN_PACKAGE_FQ_NAME = FqNameUnsafe("org.jetbrains.kotlin.idea.refactoring.move.<unknown-package>")
|
||||
|
||||
@@ -325,14 +322,14 @@ public fun moveFilesOrDirectories(
|
||||
|
||||
val initialTargetDirectory = MoveFilesOrDirectoriesUtil.getInitialTargetDirectory(targetDirectory, elements)
|
||||
|
||||
fun doRun(moveDialog: MoveFilesOrDirectoriesDialog?) {
|
||||
fun doRun(moveDialog: KotlinAwareMoveFilesOrDirectoriesDialog?) {
|
||||
fun closeDialog() {
|
||||
moveDialog?.close(DialogWrapper.CANCEL_EXIT_CODE)
|
||||
}
|
||||
|
||||
project.executeCommand(MoveHandler.REFACTORING_NAME) {
|
||||
val selectedDir = if (moveDialog != null) moveDialog.getTargetDirectory() else initialTargetDirectory
|
||||
val updatePackageDirective = (moveDialog as? MoveFilesOrDirectoriesDialogWithKotlinOptions)?.updatePackageDirective
|
||||
val selectedDir = if (moveDialog != null) moveDialog.targetDirectory else initialTargetDirectory
|
||||
val updatePackageDirective = (moveDialog as? KotlinAwareMoveFilesOrDirectoriesDialog)?.updatePackageDirective
|
||||
|
||||
try {
|
||||
val choice = if (elements.size() > 1 || elements[0] is PsiDirectory) intArrayOf(-1) else null
|
||||
@@ -375,7 +372,7 @@ public fun moveFilesOrDirectories(
|
||||
return
|
||||
}
|
||||
|
||||
with(MoveFilesOrDirectoriesDialogWithKotlinOptions(project, ::doRun)) {
|
||||
with(KotlinAwareMoveFilesOrDirectoriesDialog(project, ::doRun)) {
|
||||
setData(elements, initialTargetDirectory, "refactoring.moveFile")
|
||||
show()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user