diff --git a/CHANGELOG.md b/CHANGELOG.md index c6e1aec41..fef263d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to the Zowe™ Explorer plug-in for IntelliJ IDEA™ will be ## `1.1.2 (2024-01-22)` +* Feature: GitHub issue #165: IntelliJ 2023.3 support ([81f24fa3](https://github.com/zowe/zowe-explorer-intellij/commit/81f24fa3)) + + * Bugfix: Sync action does not work after file download ([bfb125d7](https://github.com/zowe/zowe-explorer-intellij/commit/bfb125d7)) * Bugifx: "Skip This Files" doesn't work when uploading local file to PDS ([749b2d4b](https://github.com/zowe/zowe-explorer-intellij/commit/749b2d4b)) * Bugifx: "Use new name" doesn't work for copying partitioned dataset to USS folder ([26d865be](https://github.com/zowe/zowe-explorer-intellij/commit/26d865be)) diff --git a/build.gradle.kts b/build.gradle.kts index eafcc5e51..ecbe00d67 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -98,12 +98,12 @@ tasks { patchPluginXml { sinceBuild.set("231.8109") - untilBuild.set("232.*") + untilBuild.set("233.*") changeNotes.set( """ New features:
Fixed bugs: diff --git a/src/main/kotlin/org/zowe/explorer/config/MainframeConfigurable.kt b/src/main/kotlin/org/zowe/explorer/config/MainframeConfigurable.kt index 2ed5271c3..2c6dc5a23 100755 --- a/src/main/kotlin/org/zowe/explorer/config/MainframeConfigurable.kt +++ b/src/main/kotlin/org/zowe/explorer/config/MainframeConfigurable.kt @@ -13,6 +13,7 @@ package org.zowe.explorer.config import com.intellij.openapi.components.service import com.intellij.openapi.options.Configurable import com.intellij.openapi.options.TabbedConfigurable +import com.intellij.openapi.progress.runBackgroundableTask import org.zowe.explorer.config.settings.ui.SettingsConfigurable /** @@ -55,8 +56,10 @@ class MainframeConfigurable : TabbedConfigurable() { * @see com.intellij.openapi.options.UnnamedConfigurable.reset */ override fun reset() { - ConfigSandbox.instance.fetch() - super.reset() + runBackgroundableTask(title = "Reset changes", cancellable = false) { + ConfigSandbox.instance.fetch() + super.reset() + } } /** diff --git a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ConnectionDialog.kt b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ConnectionDialog.kt index 429befcfe..0e6fff6fb 100644 --- a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ConnectionDialog.kt +++ b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ConnectionDialog.kt @@ -12,6 +12,7 @@ package org.zowe.explorer.config.connect.ui.zosmf import com.intellij.icons.AllIcons import com.intellij.openapi.components.service +import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.project.Project import com.intellij.openapi.ui.MessageDialogBuilder import com.intellij.openapi.ui.MessageType @@ -360,11 +361,13 @@ class ConnectionDialog( state.password = getPassword(lastSuccessfulState.connectionConfig) state.isAllowSsl = lastSuccessfulState.isAllowSsl state.zVersion = lastSuccessfulState.zVersion - CredentialService.instance.setCredentials( - connectionConfigUuid = lastSuccessfulState.connectionUuid, - username = getUsername(lastSuccessfulState.connectionConfig), - password = getPassword(lastSuccessfulState.connectionConfig) - ) + runBackgroundableTask("Setting credentials", project, false) { + CredentialService.instance.setCredentials( + connectionConfigUuid = lastSuccessfulState.connectionUuid, + username = getUsername(lastSuccessfulState.connectionConfig), + password = getPassword(lastSuccessfulState.connectionConfig) + ) + } } } diff --git a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt index 4252070fc..5925cab49 100644 --- a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt +++ b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt @@ -13,6 +13,7 @@ package org.zowe.explorer.config.connect.ui.zosmf import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.invokeLater import com.intellij.openapi.options.BoundSearchableConfigurable +import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.showOkCancelDialog @@ -287,11 +288,13 @@ class ZOSMFConnectionConfigurable : BoundSearchableConfigurable("z/OSMF Connecti /** Reset the Connections table changes. Updates UI when the changes were introduced */ override fun reset() { - val wasModified = isModified - rollbackSandbox() - rollbackSandbox() - if (wasModified) { - panel?.updateUI() + runBackgroundableTask(title = "Reset changes", cancellable = false) { + val wasModified = isModified + rollbackSandbox() + rollbackSandbox() + if (wasModified) { + panel?.updateUI() + } } } diff --git a/src/main/kotlin/org/zowe/explorer/editor/FileEditorFocusListener.kt b/src/main/kotlin/org/zowe/explorer/editor/FileEditorFocusListener.kt index a6903770b..ce71fdec5 100644 --- a/src/main/kotlin/org/zowe/explorer/editor/FileEditorFocusListener.kt +++ b/src/main/kotlin/org/zowe/explorer/editor/FileEditorFocusListener.kt @@ -10,10 +10,12 @@ package org.zowe.explorer.editor +import com.intellij.openapi.application.runInEdt import com.intellij.openapi.components.service import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.ex.EditorEx import com.intellij.openapi.editor.ex.FocusChangeListener +import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.ui.isComponentUnderMouse import org.zowe.explorer.config.ConfigService import org.zowe.explorer.dataops.DataOpsManager @@ -57,12 +59,20 @@ class FileEditorFocusListener: FocusChangeListener { val previousContent = contentSynchronizer?.successfulContentStorage(syncProvider) val needToUpload = contentSynchronizer?.isFileUploadNeeded(syncProvider) == true if (!(currentContent contentEquals previousContent) && needToUpload) { - val incompatibleEncoding = !checkEncodingCompatibility(file, project) - if (incompatibleEncoding && !showSaveAnywayDialog(file.charset)) { - return + runBackgroundableTask( + title = "Synchronizing ${file.name}...", + project = project, + cancellable = true + ) { + val incompatibleEncoding = !checkEncodingCompatibility(file, project) + runInEdt { + if (incompatibleEncoding && !showSaveAnywayDialog(file.charset)) { + return@runInEdt + } + runWriteActionInEdtAndWait { syncProvider.saveDocument() } + sendTopic(AutoSyncFileListener.AUTO_SYNC_FILE, project).sync(file) + } } - runWriteActionInEdtAndWait { syncProvider.saveDocument() } - sendTopic(AutoSyncFileListener.AUTO_SYNC_FILE, project).sync(file) } } } diff --git a/src/main/kotlin/org/zowe/explorer/editor/ProjectCloseListener.kt b/src/main/kotlin/org/zowe/explorer/editor/ProjectCloseListener.kt index e0141d718..b49a794a3 100644 --- a/src/main/kotlin/org/zowe/explorer/editor/ProjectCloseListener.kt +++ b/src/main/kotlin/org/zowe/explorer/editor/ProjectCloseListener.kt @@ -10,6 +10,7 @@ package org.zowe.explorer.editor +import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.project.ProjectManagerListener @@ -69,9 +70,11 @@ class ProjectCloseListener : ProjectManagerListener { * @param project the project to filter encoding mappings. */ override fun projectClosingBeforeSave(project: Project) { - val encodingManager = EncodingProjectManager.getInstance(project) as EncodingProjectManagerImpl - val filteredMappings = encodingManager.allMappings.toMutableMap().filter { it.key !is MFVirtualFile } - encodingManager.setMapping(filteredMappings) + runWriteAction { + val encodingManager = EncodingProjectManager.getInstance(project) as EncodingProjectManagerImpl + val filteredMappings = encodingManager.allMappings.toMutableMap().filter { it.key !is MFVirtualFile } + encodingManager.setMapping(filteredMappings) + } super.projectClosingBeforeSave(project) } } diff --git a/src/main/kotlin/org/zowe/explorer/explorer/ui/WorkingSetNode.kt b/src/main/kotlin/org/zowe/explorer/explorer/ui/WorkingSetNode.kt index 46f9f6e6c..cb08083dd 100644 --- a/src/main/kotlin/org/zowe/explorer/explorer/ui/WorkingSetNode.kt +++ b/src/main/kotlin/org/zowe/explorer/explorer/ui/WorkingSetNode.kt @@ -13,6 +13,7 @@ package org.zowe.explorer.explorer.ui import com.intellij.icons.AllIcons import com.intellij.ide.projectView.PresentationData import com.intellij.ide.util.treeView.AbstractTreeNode +import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.project.Project import com.intellij.ui.LayeredIcon import com.intellij.ui.SimpleTextAttributes @@ -80,10 +81,13 @@ abstract class WorkingSetNode( * @param presentation the presentation, which explanatory text will be assigned to */ protected fun addInfo(presentation: PresentationData) { - val connectionConfig = value.connectionConfig ?: return - val url = value.connectionConfig?.url ?: return - val username = getUsername(connectionConfig) - val formedUsername = if (connectionConfig.zoweConfigPath == null) username else "*".repeat(username.length) - presentation.addText(" $formedUsername on ${connectionConfig.name} [${url}]", SimpleTextAttributes.GRAYED_ATTRIBUTES) + runBackgroundableTask("Getting connection information", project, false) { + val connectionConfig = value.connectionConfig ?: return@runBackgroundableTask + val url = value.connectionConfig?.url ?: return@runBackgroundableTask + val username = getUsername(connectionConfig) + val formedUsername = if (connectionConfig.zoweConfigPath == null) username else "*".repeat(username.length) + presentation.addText(" $formedUsername on ${connectionConfig.name} [${url}]", SimpleTextAttributes.GRAYED_ATTRIBUTES) + apply(presentation) + } } } diff --git a/src/main/kotlin/org/zowe/explorer/utils/encodingUtils.kt b/src/main/kotlin/org/zowe/explorer/utils/encodingUtils.kt index 1f88cab03..06d124dd8 100644 --- a/src/main/kotlin/org/zowe/explorer/utils/encodingUtils.kt +++ b/src/main/kotlin/org/zowe/explorer/utils/encodingUtils.kt @@ -18,6 +18,7 @@ import com.intellij.ide.IdeBundle import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.DefaultActionGroup +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.impl.LoadTextUtil import com.intellij.openapi.project.DumbAwareAction @@ -224,7 +225,7 @@ fun createCharsetsActionGroup(virtualFile: VirtualFile, attributes: RemoteUssAtt */ fun checkEncodingCompatibility(file: VirtualFile, project: Project): Boolean { var compatible = true - val psiFile = PsiManager.getInstance(project).findFile(file) + val psiFile = runReadAction { PsiManager.getInstance(project).findFile(file) } psiFile?.let { val inspectionProfile = InspectionProjectProfileManager.getInstance(project).currentProfile val inspectionTool = inspectionProfile.getInspectionTool("ZoweMFLossyEncoding", project) diff --git a/src/main/kotlin/org/zowe/explorer/vfs/MFVirtualFile.kt b/src/main/kotlin/org/zowe/explorer/vfs/MFVirtualFile.kt index 5bb24f497..2ed0a171d 100755 --- a/src/main/kotlin/org/zowe/explorer/vfs/MFVirtualFile.kt +++ b/src/main/kotlin/org/zowe/explorer/vfs/MFVirtualFile.kt @@ -32,7 +32,7 @@ class MFVirtualFile internal constructor( ) : VirtualFile(), VirtualFileWithId, ReadWriteLock by ReentrantReadWriteLock() { companion object { - private val fs = MFVirtualFileSystem.instance + private val fs by lazy { MFVirtualFileSystem.instance } } @Volatile diff --git a/src/test/kotlin/org/zowe/explorer/editor/EditorTestSpec.kt b/src/test/kotlin/org/zowe/explorer/editor/EditorTestSpec.kt index 16772740c..e794f80f5 100644 --- a/src/test/kotlin/org/zowe/explorer/editor/EditorTestSpec.kt +++ b/src/test/kotlin/org/zowe/explorer/editor/EditorTestSpec.kt @@ -117,6 +117,8 @@ class EditorTestSpec : WithApplicationShouldSpec({ val bytes = byteArrayOf(116, 101, 120, 116) every { contentSynchronizerMock.successfulContentStorage(any()) } returns bytes + every { virtualFileMock.name } returns "fileName" + var currentBytes: ByteArray mockkConstructor(DocumentedSyncProvider::class)