Coverage Summary for Class: ActionResultPreviewComponent (ru.eda.plgn.bizgen.plugin.ui)

Class Method, % Branch, % Line, % Instruction, %
ActionResultPreviewComponent 0% (0/11) 0% (0/4) 0% (0/52) 0% (0/321)
ActionResultPreviewComponent$Companion 0% (0/1) 0% (0/3) 0% (0/10)
Total 0% (0/12) 0% (0/4) 0% (0/55) 0% (0/331)


 package ru.eda.plgn.bizgen.plugin.ui
 
 import com.intellij.icons.AllIcons
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.application.runWriteAction
 import com.intellij.openapi.command.undo.UndoUtil
 import com.intellij.openapi.editor.Document
 import com.intellij.openapi.editor.EditorFactory
 import com.intellij.openapi.editor.ex.EditorEx
 import com.intellij.openapi.util.Disposer
 import com.intellij.ui.InplaceButton
 import com.intellij.ui.dsl.builder.AlignX
 import com.intellij.ui.dsl.builder.RightGap
 import com.intellij.ui.dsl.builder.panel
 import com.intellij.util.ui.JBUI
 import ru.eda.plgn.bizgen.core.generator.Generator
 import ru.eda.plgn.bizgen.plugin.actions.BizGenSelectedActionEvent
 import java.awt.BorderLayout
 import javax.swing.JLabel
 import javax.swing.JPanel
 import javax.swing.JSeparator
 import kotlin.random.Random
 
 /**
  * Компонент, который применяется в настройках плагина.
  *
  * Служит для отображения результатов выбранного генератора.
  *
  * @author Dmitry_Emelyanenko
  */
 class ActionResultPreviewComponent : Disposable {
 
   /** Выбранный генератор. */
   private var selectedGenerator: Generator<*>? = null
 
   /** Для обновления состояния компонента. */
   private var seed = Random.nextInt()
 
   /** Содержит результат работы генератора. */
   private lateinit var previewEditor: EditorEx
 
   /** Кнопка для повторного запуска выбранного генератора. */
   private lateinit var refreshButton: InplaceButton
 
   /** Содержит идентификатор генератора. */
   private lateinit var actionIdLabel: JLabel
 
   private var uniqueDistanceLabel: JLabel = JLabel("")
 
   /** Основной компонент панели "Настройки плагина". */
   val rootComponent: JPanel = panel {
     // разделитель с отображением идентификатора выбранного генератора и кнопкой для повторного запуска выбранного генератора
     row {
       val separatorPanel = JPanel(BorderLayout()).apply {
         actionIdLabel = JLabel("ActionID: ").apply {
           border = JBUI.Borders.emptyRight(5)
         }
         add(actionIdLabel, BorderLayout.WEST)
         add(JSeparator(), BorderLayout.CENTER)
         border = JBUI.Borders.empty(5)
       }
       cell(separatorPanel)
 
       refreshButton = InplaceButton("Generate", AllIcons.Actions.Refresh) {
         seed = Random.nextInt()
         updatePreviewTextByGenerator()
       }
       cell(refreshButton).align(AlignX.RIGHT)
     }
 
     row {
       label("Дистанция уникальности").gap(RightGap.SMALL)
       contextHelp(DISTANCE_HELP_MESSAGE).gap(RightGap.SMALL)
       label(":")
       cell(uniqueDistanceLabel)
     }
 
     // содержит область для отображения результатов выбранного генератора
     row {
       val factory = EditorFactory.getInstance()
       val previewDocument = factory.createDocument("Выберите генератор").also {
         UndoUtil.disableUndoFor(it)
       }
       previewEditor = factory.createEditor(previewDocument) as EditorEx
 
       cell(previewEditor.component.apply {
         preferredSize = JBUI.size(600, 200)
         minimumSize = preferredSize
         maximumSize = preferredSize
       }).align(AlignX.FILL)
     }
   }
 
   init {
     Disposer.register(this) {
       EditorFactory.getInstance().releaseEditor(previewEditor)
     }
 
     BizGenSelectedActionEvent.subscribeAsync(this) { action ->
       selectedGenerator = action.generator
       actionIdLabel.text = "ActionID: ${action.id}"
       uniqueDistanceLabel.text = "${action.generator.uniqueDistance}"
       updatePreviewTextByGenerator()
     }
   }
 
   private fun updatePreviewTextByGenerator() {
     val result = selectedGenerator?.generate() ?: return
 
     val resultText = """
       Общая длина вставляемого текста: ${result.toEditor.length}
       
       Вставляемый текст в редактор:
       ${result.toEditor}
       
       Копируемый в текст в буфер обмена:
       ${result.toClipboard}
       """.trimIndent()
 
     runWriteAction {
       previewEditor.document.setTextInReadOnly(resultText)
     }
   }
 
   /** Освобождение ресурса. */
   override fun dispose() = Unit
 
   private companion object {
     const val DISTANCE_HELP_MESSAGE =
       "Количество вызовов генератора, при котором с вероятностью 95% получается разный результат. Значения выше 130 не проверялись, поэтому реальные значения могут быть значительно больше"
 
     /**
      * Чтобы документ был в режиме только просмотра, специально перед вставкой текста снимаем этот режим, потом вставляем текст, а потом
      * опять возвращаем режим только для просмотра.
      *
      * @param text вставляемый текст
      */
     fun Document.setTextInReadOnly(text: String) {
       setReadOnly(false)
       setText(text)
       setReadOnly(true)
     }
   }
 }