[pycharm] PY-79113 Debugger: tie actions to group

(cherry picked from commit e8b76889b27d78288905dd7f86e41d66df3858de)

GitOrigin-RevId: f0bb0de30a1070e5744abb8e94b4a407fe040d55
This commit is contained in:
ekaterina.itsenko
2025-02-26 11:20:53 +01:00
committed by intellij-monorepo-bot
parent 3c9ddf8cdd
commit 8efcf30d5e
5 changed files with 166 additions and 20 deletions

View File

@@ -89,7 +89,6 @@ image.description={0}\u00D7{1}, {2}bpp
dialog.title.save.image=Select File to Save Image
action.Images.SaveImageAction.text=Save Image
action.Images.CopyImageAction.text=Copy Image
group.Images.ImageOperationsGroup.text=Hi there
image.color.mode.rgb=RGB
image.color.mode.bgr=BGR
image.color.mode.grayscale=Grayscale
image.color.mode.original.image=Original
image.color.mode.inverted.image=Inverted
image.color.mode.grayscale.image=Grayscale

View File

@@ -0,0 +1,53 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.images.scientific.action
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.DumbAwareAction
import org.intellij.images.editor.ImageEditor
import org.intellij.images.scientific.ScientificUtils
import org.intellij.images.ui.ImageComponent
import java.awt.image.BufferedImage
class BGRAction : DumbAwareAction() {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
override fun update(e: AnActionEvent) {
val imageFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
e.presentation.isEnabledAndVisible = imageFile?.getUserData(ScientificUtils.SCIENTIFIC_MODE_KEY) != null
}
override fun actionPerformed(e: AnActionEvent) {
val imageEditor = getImageEditor(e) ?: return
val imageComponent = getImageComponent(imageEditor) ?: return
val document = imageComponent.document
val originalImage = document.value ?: return
val bgrImage = applyInvertChannels(originalImage)
document.setValue(bgrImage) // TODO: how to view result without changing original image?
}
private fun applyInvertChannels(image: BufferedImage): BufferedImage {
val invertedImage = BufferedImage(image.width, image.height, image.type)
for (x in 0 until image.width) {
for (y in 0 until image.height) {
val rgb = image.getRGB(x, y)
val red = (rgb shr 16) and 0xFF
val green = (rgb shr 8) and 0xFF
val blue = rgb and 0xFF
val bgr = (blue shl 16) or (green shl 8) or red
invertedImage.setRGB(x, y, bgr)
}
}
return invertedImage
}
private fun getImageEditor(e: AnActionEvent): ImageEditor? {
return null
}
private fun getImageComponent(imageEditor: ImageEditor): ImageComponent? {
return null
}
}

View File

@@ -0,0 +1,54 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.images.scientific.action
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.DumbAwareAction
import org.intellij.images.editor.ImageEditor
import org.intellij.images.scientific.ScientificUtils
import org.intellij.images.ui.ImageComponent
import java.awt.Color
import java.awt.image.BufferedImage
class GrayscaleAction : DumbAwareAction() {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
override fun update(e: AnActionEvent) {
val imageFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
e.presentation.isEnabledAndVisible = imageFile?.getUserData(ScientificUtils.SCIENTIFIC_MODE_KEY) != null
}
override fun actionPerformed(e: AnActionEvent) {
val imageEditor = getImageEditor(e) ?: return
val imageComponent = getImageComponent(imageEditor) ?: return
val document = imageComponent.document
val originalImage = document.value ?: return
val grayscaleImage = applyGrayscale(originalImage)
document.setValue(grayscaleImage) // TODO: how to view result without changing original image?
}
private fun getImageEditor(e: AnActionEvent): ImageEditor? {
return null
}
private fun getImageComponent(imageEditor: ImageEditor): ImageComponent? {
return null
}
// TODO: maybe redo logic, its just a stub!
private fun applyGrayscale(image: BufferedImage): BufferedImage {
val grayscaleImage = BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_RGB)
for (x in 0 until image.width) {
for (y in 0 until image.height) {
val pixel = Color(image.getRGB(x, y))
val gray = (pixel.red * 0.299 + pixel.green * 0.587 + pixel.blue * 0.114).toInt()
val grayColor = Color(gray, gray, gray)
grayscaleImage.setRGB(x, y, grayColor.rgb)
}
}
return grayscaleImage
}
}

View File

@@ -3,7 +3,6 @@ package org.intellij.images.scientific.action
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.actionSystem.ex.CustomComponentAction
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.popup.JBPopupFactory
import org.intellij.images.ImagesBundle
@@ -15,8 +14,8 @@ import javax.swing.JPanel
class ImageOperationsActionGroup : DefaultActionGroup(), CustomComponentAction, DumbAware {
private var selectedMode: String = RGB
private val availableModes = listOf(RGB, BGR, GRAYSCALE)
private var selectedMode: String = ORIGINAL_IMAGE
private val availableModes = listOf(ORIGINAL_IMAGE, INVERTED_IMAGE, GRAYSCALE_IMAGE)
init {
templatePresentation.apply {
@@ -33,9 +32,8 @@ class ImageOperationsActionGroup : DefaultActionGroup(), CustomComponentAction,
null,
createPopupActionGroup(),
e.dataContext,
null,
true,
null
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
true
).showUnderneathOf(component)
}
@@ -50,6 +48,7 @@ class ImageOperationsActionGroup : DefaultActionGroup(), CustomComponentAction,
isOpaque = false
addActionListener {
selectedMode = selectedItem as String
triggerModeAction(selectedMode)
}
}
return JPanel(BorderLayout()).apply {
@@ -61,19 +60,24 @@ class ImageOperationsActionGroup : DefaultActionGroup(), CustomComponentAction,
private fun createPopupActionGroup(): DefaultActionGroup {
val actionGroup = DefaultActionGroup()
availableModes.forEach { mode ->
actionGroup.add(
DumbAwareAction.create(mode) {
selectedMode = mode
}
)
}
actionGroup.add(RGBAction())
actionGroup.add(BGRAction())
actionGroup.add(GrayscaleAction())
return actionGroup
}
private fun triggerModeAction(mode: String) {
val actionManager = ActionManager.getInstance()
when (mode) {
ORIGINAL_IMAGE -> actionManager.tryToExecute(RGBAction(), null, null, null, true)
INVERTED_IMAGE -> actionManager.tryToExecute(BGRAction(), null, null, null, true)
GRAYSCALE_IMAGE -> actionManager.tryToExecute(GrayscaleAction(), null, null, null, true)
}
}
companion object {
private val RGB: String = ImagesBundle.message("image.color.mode.rgb")
private val BGR: String = ImagesBundle.message("image.color.mode.bgr")
private val GRAYSCALE: String = ImagesBundle.message("image.color.mode.grayscale")
private val ORIGINAL_IMAGE: String = ImagesBundle.message("image.color.mode.original.image")
private val INVERTED_IMAGE: String = ImagesBundle.message("image.color.mode.inverted.image")
private val GRAYSCALE_IMAGE: String = ImagesBundle.message("image.color.mode.grayscale.image")
}
}

View File

@@ -0,0 +1,36 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.images.scientific.action
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.DumbAwareAction
import org.intellij.images.editor.ImageEditor
import org.intellij.images.scientific.ScientificUtils
import org.intellij.images.ui.ImageComponent
class RGBAction : DumbAwareAction() {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
override fun update(e: AnActionEvent) {
val imageFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
e.presentation.isEnabledAndVisible = imageFile?.getUserData(ScientificUtils.SCIENTIFIC_MODE_KEY) != null
}
override fun actionPerformed(e: AnActionEvent) {
val imageEditor = getImageEditor(e) ?: return
val imageComponent = getImageComponent(imageEditor) ?: return
val document = imageComponent.document
val originalImage = document.value ?: return
document.setValue(originalImage) // TODO: restore original image!
}
private fun getImageEditor(e: AnActionEvent): ImageEditor? {
return null
}
private fun getImageComponent(imageEditor: ImageEditor): ImageComponent? {
return null
}
}