Skip to content

Commit ed384c3

Browse files
committed
improve the steps UI
1 parent f6f77f6 commit ed384c3

File tree

1 file changed

+63
-47
lines changed

1 file changed

+63
-47
lines changed

src/main/kotlin/com/github/adrienpessu/sarifviewer/toolWindow/SarifViewerWindowFactory.kt

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,11 @@ import java.nio.charset.Charset
5555
import java.nio.file.Files
5656
import java.nio.file.Path
5757
import javax.swing.*
58-
import javax.swing.event.HyperlinkEvent
59-
import javax.swing.event.HyperlinkListener
6058
import javax.swing.event.TreeSelectionEvent
6159
import javax.swing.event.TreeSelectionListener
6260
import javax.swing.filechooser.FileNameExtensionFilter
6361
import javax.swing.table.DefaultTableCellRenderer
6462
import javax.swing.table.DefaultTableModel
65-
import javax.swing.text.html.HTMLEditorKit
6663
import javax.swing.tree.DefaultMutableTreeNode
6764
import javax.swing.tree.DefaultTreeModel
6865

@@ -112,7 +109,7 @@ class SarifViewerWindowFactory : ToolWindowFactory {
112109
private var comboBranchPR = ComboBox(arrayOf(BranchItemComboBox(0, "main", "", "")))
113110
private val tableInfos = JBTable(DefaultTableModel(arrayOf<Any>("Property", "Value"), 0))
114111
private val tableSteps = JBTable(DefaultTableModel(arrayOf<Any>("Path"), 0))
115-
private val steps = JEditorPane()
112+
private val steps = JPanel()
116113
private val errorField = JLabel("Error message here ")
117114
private val errorToolbar = JToolBar("", JToolBar.HORIZONTAL)
118115
private val loadingPanel = JPanel()
@@ -265,16 +262,9 @@ class SarifViewerWindowFactory : ToolWindowFactory {
265262
}
266263

267264
private fun JBPanel<JBPanel<*>>.buildSkeleton() {
268-
steps.isEditable = false
269-
steps.addHyperlinkListener(object : HyperlinkListener {
270-
override fun hyperlinkUpdate(hle: HyperlinkEvent?) {
271-
if (HyperlinkEvent.EventType.ACTIVATED == hle?.eventType) {
272-
hle?.description.toString().split(":").let { location ->
273-
openFile(project, location[0], location[1].toInt())
274-
}
275-
}
276-
}
277-
})
265+
steps.layout = BoxLayout(steps, BoxLayout.Y_AXIS)
266+
tableSteps.size = Dimension(steps.width, steps.height)
267+
steps.add(tableSteps)
278268

279269
// Add the table to a scroll pane
280270
val scrollPane = JScrollPane(tableInfos)
@@ -486,7 +476,12 @@ class SarifViewerWindowFactory : ToolWindowFactory {
486476
defaultTableModel.addRow(arrayOf<Any>("Rule's description", leaf.ruleDescription))
487477
defaultTableModel.addRow(arrayOf<Any>("Location", leaf.location))
488478
defaultTableModel.addRow(arrayOf<Any>("GitHub alert number", leaf.githubAlertNumber))
489-
defaultTableModel.addRow(arrayOf<Any>("GitHub alert url", "<a href=\"$githubAlertUrl\">$githubAlertUrl</a"))
479+
defaultTableModel.addRow(
480+
arrayOf<Any>(
481+
"GitHub alert url",
482+
"<a href=\"$githubAlertUrl\">$githubAlertUrl</a"
483+
)
484+
)
490485

491486
tableInfos.setDefaultRenderer(Object::class.java, object : DefaultTableCellRenderer() {
492487
override fun getTableCellRendererComponent(
@@ -497,7 +492,14 @@ class SarifViewerWindowFactory : ToolWindowFactory {
497492
row: Int,
498493
column: Int
499494
): Component {
500-
var c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column)
495+
var c = super.getTableCellRendererComponent(
496+
table,
497+
value,
498+
isSelected,
499+
hasFocus,
500+
row,
501+
column
502+
)
501503
if (row == tableInfos.rowCount - 1 && column == tableInfos.columnCount - 1) {
502504
val url = tableInfos.getValueAt(row, column).toString()
503505
c = JLabel("<html><a href='$url'>$url</a></html>")
@@ -514,7 +516,9 @@ class SarifViewerWindowFactory : ToolWindowFactory {
514516
val column = tableInfos.columnAtPoint(e.point)
515517
if (row == tableInfos.rowCount - 1) {
516518
if (column == tableInfos.columnCount - 1) {
517-
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
519+
if (Desktop.isDesktopSupported() && Desktop.getDesktop()
520+
.isSupported(Desktop.Action.BROWSE)
521+
) {
518522
Desktop.getDesktop().browse(URI(githubAlertUrl))
519523
}
520524
}
@@ -524,11 +528,21 @@ class SarifViewerWindowFactory : ToolWindowFactory {
524528

525529
tableInfos.updateUI()
526530

527-
steps.read(leaf.steps.joinToString(" ", "<ul>", "</ul>") { step ->
528-
"<li><a href=\"$step\">${step.split("/").last()}</a></li>"
529-
}.byteInputStream(Charset.defaultCharset()), HTMLEditorKit::class.java)
531+
tableSteps.clearSelection()
530532

531-
steps.contentType = "text/html"
533+
tableSteps.model = DefaultTableModel(arrayOf<Any>("Path"), 0)
534+
535+
leaf.steps.forEachIndexed { index, step ->
536+
(tableSteps.model as DefaultTableModel).addRow(arrayOf<Any>("$index $step"))
537+
}
538+
539+
tableSteps.addMouseListener(object : MouseAdapter() {
540+
override fun mouseClicked(e: MouseEvent) {
541+
val row = tableInfos.rowAtPoint(e.point)
542+
val path = leaf.steps[row].split(":")
543+
openFile(project, path[0], path[1].toInt())
544+
}
545+
})
532546

533547
details.isVisible = true
534548
openFile(
@@ -579,32 +593,33 @@ class SarifViewerWindowFactory : ToolWindowFactory {
579593
true // request focus to editor
580594
)
581595
FileDocumentManager.getInstance().getDocument(virtualFile)?.let { document ->
582-
val lineStartOffset = document.getLineStartOffset(lineNumber - 1)
583-
val lineEndOffset = document.getLineEndOffset(lineNumber - 1)
584-
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
585-
editor.caretModel.moveToOffset(lineStartOffset)
586-
editor.scrollingModel.scrollToCaret(ScrollType.CENTER)
587-
editor.selectionModel.setSelection(lineStartOffset, lineEndOffset)
588-
589-
val messageType = when (level) {
590-
"error" -> MessageType.ERROR
591-
"warning" -> MessageType.WARNING
592-
else -> MessageType.INFO
593-
}
594-
595-
// add a balloon on the selection
596-
val balloon = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(
597-
ruleDescription,
598-
messageType,
599-
null
600-
).createBalloon()
601-
balloon.show(
602-
RelativePoint(
603-
editor.contentComponent,
604-
editor.visualPositionToXY(editor.caretModel.visualPosition)
605-
), Balloon.Position.above
606-
)
596+
if (ruleDescription.isNotEmpty()) {
597+
val lineStartOffset = document.getLineStartOffset(lineNumber - 1)
598+
val lineEndOffset = document.getLineEndOffset(lineNumber - 1)
599+
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return
600+
editor.caretModel.moveToOffset(lineStartOffset)
601+
editor.scrollingModel.scrollToCaret(ScrollType.CENTER)
602+
editor.selectionModel.setSelection(lineStartOffset, lineEndOffset)
603+
604+
val messageType = when (level) {
605+
"error" -> MessageType.ERROR
606+
"warning" -> MessageType.WARNING
607+
else -> MessageType.INFO
608+
}
607609

610+
// add a balloon on the selection
611+
val balloon = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(
612+
ruleDescription,
613+
messageType,
614+
null
615+
).createBalloon()
616+
balloon.show(
617+
RelativePoint(
618+
editor.contentComponent,
619+
editor.visualPositionToXY(editor.caretModel.visualPosition)
620+
), Balloon.Position.above
621+
)
622+
}
608623
}
609624

610625
}
@@ -620,7 +635,8 @@ class SarifViewerWindowFactory : ToolWindowFactory {
620635

621636
tableInfos.clearSelection()
622637
tableInfos.updateUI()
623-
steps.text = ""
638+
tableSteps.clearSelection()
639+
tableSteps.updateUI()
624640
details.isVisible = false
625641
errorToolbar.isVisible = false
626642
}

0 commit comments

Comments
 (0)