diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/DiffHeaderPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/DiffHeaderPanel.kt index 9cde05f1..fc742c25 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/DiffHeaderPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/DiffHeaderPanel.kt @@ -3,17 +3,12 @@ package ee.carlrobert.codegpt.toolwindow.chat.editor.header import com.intellij.diff.tools.fragmented.UnifiedDiffChange import com.intellij.openapi.application.runInEdt import com.intellij.ui.AnimatedIcon -import com.intellij.ui.JBColor -import com.intellij.ui.SimpleColoredComponent import com.intellij.ui.components.ActionLink import com.intellij.ui.components.JBLabel -import com.intellij.util.ui.JBUI import ee.carlrobert.codegpt.CodeGPTBundle import ee.carlrobert.codegpt.toolwindow.chat.editor.ResponseEditorPanel import ee.carlrobert.codegpt.toolwindow.chat.editor.diff.DiffAcceptedPanel -import ee.carlrobert.codegpt.toolwindow.chat.editor.diff.DiffStatsComponent import java.awt.BorderLayout -import javax.swing.Box import javax.swing.BoxLayout import javax.swing.JPanel @@ -34,19 +29,14 @@ class DiffHeaderPanel( AnimatedIcon.Default(), JBLabel.LEFT ) + private val actionLinksPanel = JPanel().apply { layout = BoxLayout(this, BoxLayout.X_AXIS) isVisible = false add(ActionLink("View Diff") { actions.onOpenDiff() }) - add(Box.createHorizontalStrut(4)) - add(JBLabel("ยท").apply { - font = JBUI.Fonts.smallFont() - foreground = JBColor.GRAY - }) - add(Box.createHorizontalStrut(4)) + add(separator()) add(ActionLink(CodeGPTBundle.get("shared.acceptAll")) { actions.onAcceptAll() }) } - private val statsComponent: SimpleColoredComponent = SimpleColoredComponent() init { setupUI() @@ -56,8 +46,6 @@ class DiffHeaderPanel( if (config.readOnly) return rightPanel.apply { - add(statsComponent) - add(separator()) add(actionLinksPanel) add(loadingLabel) } @@ -86,22 +74,10 @@ class DiffHeaderPanel( container.add(diffAcceptedPanel, BorderLayout.CENTER) container.revalidate() container.repaint() - } else { - setRightPanelComponent(diffAcceptedPanel) - revalidate() - repaint() } } } - fun updateDiffStats(changes: List) { - runInEdt { - DiffStatsComponent.updateStatsComponent(statsComponent, changes) - revalidate() - repaint() - } - } - fun editing() { runInEdt { loadingLabel.text = CodeGPTBundle.get("toolwindow.chat.editor.diff.editing") diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt index eb477cca..f91b7343 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/header/HeaderPanel.kt @@ -1,22 +1,24 @@ package ee.carlrobert.codegpt.toolwindow.chat.editor.header +import com.intellij.diff.tools.fragmented.UnifiedDiffChange import com.intellij.icons.AllIcons import com.intellij.ide.actions.OpenFileAction -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.runInEdt +import com.intellij.openapi.application.runUndoTransparentWriteAction import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.editor.ex.EditorEx import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VirtualFile -import com.intellij.ui.ColorUtil -import com.intellij.ui.JBColor -import com.intellij.ui.SeparatorComponent -import com.intellij.ui.SeparatorOrientation +import com.intellij.openapi.vfs.writeText +import com.intellij.ui.* import com.intellij.ui.components.ActionLink import com.intellij.ui.components.JBLabel import com.intellij.util.ui.JBUI import com.intellij.util.ui.components.BorderLayoutPanel +import ee.carlrobert.codegpt.toolwindow.chat.editor.diff.DiffStatsComponent +import java.awt.BorderLayout +import java.awt.Dimension import java.io.File import javax.swing.BoxLayout import javax.swing.JComponent @@ -37,6 +39,10 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan private val logger = thisLogger() } + private val statsComponent = SimpleColoredComponent().apply { + font = JBUI.Fonts.smallFont() + } + protected var virtualFile: VirtualFile? = config.filePath?.let { try { LocalFileSystem.getInstance().refreshAndFindFileByIoFile(File(it)) @@ -48,25 +54,39 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan private val rightPanel = JPanel().apply { layout = BoxLayout(this, BoxLayout.X_AXIS) + alignmentY = 0.5f isOpaque = false } protected abstract fun initializeRightPanel(rightPanel: JPanel) + fun updateDiffStats(changes: List) { + runInEdt { + DiffStatsComponent.updateStatsComponent(statsComponent, changes) + revalidate() + repaint() + } + } + protected fun setupUI() { setupPanelAppearance() setupFilePathOrLanguageLabel(virtualFile) rightPanel.removeAll() initializeRightPanel(rightPanel) - addToRight(rightPanel) + + val rightCenteringPanel = JPanel(BorderLayout()).apply { + isOpaque = false + add(rightPanel, BorderLayout.CENTER) + } + addToRight(rightCenteringPanel) } protected fun setRightPanelComponent(component: JComponent?) { if (component != null) { rightPanel.removeAll() rightPanel.add(component) - revalidate() - repaint() + rightPanel.revalidate() + rightPanel.repaint() } } @@ -83,27 +103,30 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan JBUI.Borders.customLine(ColorUtil.fromHex("#48494b"), 1, 1, 0, 1), JBUI.Borders.empty(4) ) + preferredSize = Dimension(preferredSize.width, 32) + minimumSize = Dimension(preferredSize.width, 32) } protected fun setupFilePathOrLanguageLabel(virtualFile: VirtualFile?) { val filePath = config.filePath if (filePath != null) { - ApplicationManager.getApplication().executeOnPooledThread { - if (virtualFile == null) { - addComponent(createNewFileLink(filePath, config.editorEx)) - } else { - virtualFile.refresh(true, false) - addComponent(createFileLink(virtualFile)) - } + if (virtualFile == null) { + val newFileLink = createNewFileLink(filePath, config.editorEx) + addToLeft(newFileLink) + } else { + addToLeft(JPanel().apply { + layout = BoxLayout(this, BoxLayout.X_AXIS) + isOpaque = false + add(ActionLink(virtualFile.name) { + OpenFileAction.openFile(virtualFile, config.project) + }.apply { + setExternalLinkIcon() + }) + add(statsComponent) + }) } } else { - addComponent(createLanguageLabel()) - } - } - - private fun addComponent(component: JComponent) { - runInEdt { - addToLeft(component) + addToLeft(createLanguageLabel()) } } @@ -122,7 +145,6 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan if (!created) { return@ActionLink } - file.writeText(content) } catch (ex: Exception) { logger.error(ex) return@ActionLink @@ -130,21 +152,20 @@ abstract class HeaderPanel(protected val config: HeaderConfig) : BorderLayoutPan LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)?.let { newFile -> runInEdt { - OpenFileAction.openFile(newFile, config.project) + runUndoTransparentWriteAction { + newFile.writeText(content) + } + remove(actionLink) setupFilePathOrLanguageLabel(newFile) + + OpenFileAction.openFile(newFile, config.project) } } }.apply { icon = AllIcons.General.InlineAdd } return actionLink } - private fun createFileLink(virtualFile: VirtualFile): ActionLink { - return ActionLink(virtualFile.name) { - OpenFileAction.openFile(virtualFile, config.project) - }.apply { setExternalLinkIcon() } - } - private fun createLanguageLabel(): JBLabel { return JBLabel(config.language).apply { foreground = JBColor.GRAY