@@ -10,19 +10,20 @@ import com.intellij.notification.Notifications
1010import com.intellij.openapi.actionSystem.ActionUpdateThread
1111import com.intellij.openapi.actionSystem.AnAction
1212import com.intellij.openapi.actionSystem.AnActionEvent
13+ import com.intellij.openapi.actionSystem.DataContext
1314import com.intellij.openapi.progress.ProgressIndicator
1415import com.intellij.openapi.progress.ProgressManager
1516import com.intellij.openapi.progress.Task
1617import com.intellij.openapi.project.Project
17- import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase
1818import com.jetbrains.python.debugger.PyDebugValue
1919import com.jetbrains.python.debugger.PyFrameAccessor
20+ import java.lang.reflect.Modifier
2021import javax.swing.SwingUtilities
2122
2223class ViewAsImageAction : AnAction () {
2324 override fun actionPerformed (e : AnActionEvent ) {
2425 val project = e.project ? : return
25- val value = XDebuggerTreeActionBase .getSelectedValue (e.dataContext) as PyDebugValue ? ? : return
26+ val value = getSelectedPyDebugValue (e.dataContext) ? : return
2627
2728 if (! checkPythonCompatibility(value.frameAccessor, project)) {
2829 return
@@ -83,7 +84,7 @@ class ViewAsImageAction : AnAction() {
8384 override fun update (e : AnActionEvent ) {
8485 super .update(e)
8586 try {
86- val value = XDebuggerTreeActionBase .getSelectedValue (e.dataContext) as PyDebugValue
87+ val value = getSelectedPyDebugValue (e.dataContext) ? : throw IllegalStateException ( " No selected debug value " )
8788 val imageProvider = ImageProviderFactory .getImageProvider(value.typeQualifier as String )
8889 e.presentation.isVisible = imageProvider.typeSupported(value)
8990 e.presentation.isEnabled = imageProvider.shapeSupported(value)
@@ -99,6 +100,10 @@ class ViewAsImageAction : AnAction() {
99100 return if (value.parent == null ) value.name else value.evaluationExpression
100101 }
101102
103+ private fun getSelectedPyDebugValue (dataContext : DataContext ): PyDebugValue ? {
104+ return XDebuggerSelectionCompat .getSelectedValue(dataContext) as ? PyDebugValue
105+ }
106+
102107 private fun checkPythonCompatibility (frameAccessor : PyFrameAccessor , project : Project ): Boolean {
103108 val pythonVersion = Python .getInterpreterVersion(frameAccessor)
104109
@@ -139,4 +144,39 @@ class ViewAsImageAction : AnAction() {
139144
140145 return isJupyter
141146 }
142- }
147+ }
148+
149+ private object XDebuggerSelectionCompat {
150+ private val candidateClassNames = listOf (
151+ " com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeBackendOnlyActionBase" ,
152+ " com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase" ,
153+ )
154+
155+ fun getSelectedValue (dataContext : DataContext ): Any? {
156+ for (className in candidateClassNames) {
157+ val value = runCatching { invokeSelectionMethod(className, dataContext) }.getOrNull()
158+ if (value != null ) {
159+ return value
160+ }
161+ }
162+ return null
163+ }
164+
165+ private fun invokeSelectionMethod (className : String , dataContext : DataContext ): Any? {
166+ val actionClass = Class .forName(className, false , XDebuggerSelectionCompat ::class .java.classLoader)
167+ val staticMethod = actionClass.methods.firstOrNull {
168+ it.name == " getSelectedValue" && it.parameterCount == 1 && Modifier .isStatic(it.modifiers)
169+ }
170+ if (staticMethod != null ) {
171+ return staticMethod.invoke(null , dataContext)
172+ }
173+
174+ val companionField = actionClass.getDeclaredField(" Companion" )
175+ val companion = companionField.get(null )
176+ val companionMethod = companion .javaClass.methods.firstOrNull {
177+ it.name == " getSelectedValue" && it.parameterCount == 1
178+ } ? : return null
179+
180+ return companionMethod.invoke(companion , dataContext)
181+ }
182+ }
0 commit comments