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:
- - None at the moment
+ - GitHub issue #165: IntelliJ 2023.3 support
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)