From 91b85ed70cc3d9ee78b0d1dd3c1feab181b1d67e Mon Sep 17 00:00:00 2001 From: JFronny Date: Wed, 29 May 2024 14:42:24 +0200 Subject: [PATCH] feat: add settings UI and allow configuring PDF open mode Closes #1 --- README.md | 1 - .../kotlin/io/gitlab/jfronny/sdom/SDom.kt | 1 + .../jfronny/sdom/actions/SDLoginAction.kt | 18 ++++++++- .../jfronny/sdom/actions/SDStatementAction.kt | 32 +++++++++++----- .../gitlab/jfronny/sdom/settings/PdfMode.kt | 11 ++++++ .../sdom/{ => settings}/SDCredentials.kt | 6 +-- .../jfronny/sdom/{ => settings}/SDSettings.kt | 8 +++- .../sdom/settings/SDSettingsComponent.kt | 34 +++++++++++++++++ .../sdom/settings/SDSettingsConfigurable.kt | 37 +++++++++++++++++++ .../jfronny/sdom/toolwindow/SDToolWindow.kt | 11 +----- .../jfronny/sdom/ui/SDLoginDialogWrapper.kt | 2 +- src/main/resources/META-INF/plugin.xml | 4 ++ 12 files changed, 138 insertions(+), 27 deletions(-) create mode 100644 src/main/kotlin/io/gitlab/jfronny/sdom/settings/PdfMode.kt rename src/main/kotlin/io/gitlab/jfronny/sdom/{ => settings}/SDCredentials.kt (84%) rename src/main/kotlin/io/gitlab/jfronny/sdom/{ => settings}/SDSettings.kt (50%) create mode 100644 src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsComponent.kt create mode 100644 src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsConfigurable.kt diff --git a/README.md b/README.md index f5a7163..2f784f1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ You can download the plugin from the [JetBrains Marketplace](https://plugins.jet ## Potential future features -- Settings UI (login, PDF mode, ...) - Display how much time is left in a contest or whether it's already over - Implement reading detailed results - Show scoreboards diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt index 9839c54..510ba58 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt @@ -11,6 +11,7 @@ import io.gitlab.jfronny.sdom.actions.SDGetContestsAction import io.gitlab.jfronny.sdom.actions.SDGetProblemsAction import io.gitlab.jfronny.sdom.model.* import io.gitlab.jfronny.sdom.model.scoreboard.Scoreboard +import io.gitlab.jfronny.sdom.settings.SDCredentials import io.gitlab.jfronny.sdom.util.notify import io.ktor.client.* import io.ktor.client.call.* diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDLoginAction.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDLoginAction.kt index 4461be4..d39a500 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDLoginAction.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDLoginAction.kt @@ -2,8 +2,7 @@ package io.gitlab.jfronny.sdom.actions import com.intellij.notification.Notification import com.intellij.notification.NotificationAction -import com.intellij.openapi.actionSystem.ActionUpdateThread -import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.* import io.gitlab.jfronny.sdom.SDom import io.gitlab.jfronny.sdom.ui.SDLoginDialogWrapper import kotlinx.coroutines.CoroutineScope @@ -26,4 +25,19 @@ class SDLoginAction(text: String) : NotificationAction(text) { } } } + + companion object { + fun perform() { + SDLoginAction().actionPerformed( + AnActionEvent( + null, + DataContext.EMPTY_CONTEXT, + ActionPlaces.UNKNOWN, + Presentation(), + ActionManager.getInstance(), + 0 + ) + ) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDStatementAction.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDStatementAction.kt index c9f7675..7212442 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDStatementAction.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/actions/SDStatementAction.kt @@ -6,10 +6,14 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.DumbAwareAction +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.ui.jcef.JBCefApp import io.gitlab.jfronny.sdom.SDom import io.gitlab.jfronny.sdom.SDom.currentContest import io.gitlab.jfronny.sdom.SDom.currentProblem +import io.gitlab.jfronny.sdom.settings.PdfMode +import io.gitlab.jfronny.sdom.settings.SDSettings import io.gitlab.jfronny.sdom.ui.ByteVirtualFile import io.gitlab.jfronny.sdom.util.OSUtils import io.gitlab.jfronny.sdom.util.notify @@ -18,6 +22,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption class SDStatementAction(name: String) : DumbAwareAction(name) { constructor() : this("") @@ -52,16 +58,24 @@ class SDStatementAction(name: String) : DumbAwareAction(name) { } CoroutineScope(Job() + Dispatchers.IO).launch { val data = SDom.downloadProblemStatement(contest, problem) - if (JBCefApp.isSupported()) { - val virtualFile = ByteVirtualFile("${problem.name}_${contest.name}.pdf", data) - ApplicationManager.getApplication().invokeLater { - FileEditorManager.getInstance(e.project!!).openFile(virtualFile) + fun createTmpFile(): Path { + val path = Files.createTempFile("${problem.name}_${contest.name}", ".pdf") + Files.write(path, data, StandardOpenOption.WRITE) + return path + } + fun open(virtualFile: VirtualFile) = ApplicationManager.getApplication().invokeLater { + FileEditorManager.getInstance(e.project!!).openFile(virtualFile) + } + when (SDSettings.getInstance().state.pdfMode) { + PdfMode.INTERNAL_MEMORY -> { + if (JBCefApp.isSupported()) open(ByteVirtualFile("${problem.name}_${contest.name}.pdf", data)) + else OSUtils.openFile(createTmpFile().toFile()) } - } else { - val path = Files.createTempFile("sdom", ".pdf") - Files.newOutputStream(path).use { it.write(data) } - - OSUtils.openFile(path.toFile()) + PdfMode.INTERNAL_FILE -> { + if (JBCefApp.isSupported()) open(VirtualFileManager.getInstance().refreshAndFindFileByNioPath(createTmpFile())!!) + else OSUtils.openFile(createTmpFile().toFile()) + } + PdfMode.EXTERNAL_FILE -> OSUtils.openFile(createTmpFile().toFile()) } } } diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/settings/PdfMode.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/PdfMode.kt new file mode 100644 index 0000000..9be703a --- /dev/null +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/PdfMode.kt @@ -0,0 +1,11 @@ +package io.gitlab.jfronny.sdom.settings + +enum class PdfMode(private val visual: String) { + INTERNAL_MEMORY("Internal viewer, in-memory"), + INTERNAL_FILE("Internal viewer, as file"), + EXTERNAL_FILE("System-default"); + + override fun toString(): String { + return visual + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/SDCredentials.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDCredentials.kt similarity index 84% rename from src/main/kotlin/io/gitlab/jfronny/sdom/SDCredentials.kt rename to src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDCredentials.kt index f265880..40994cb 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/SDCredentials.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDCredentials.kt @@ -1,4 +1,4 @@ -package io.gitlab.jfronny.sdom +package io.gitlab.jfronny.sdom.settings import com.intellij.credentialStore.CredentialAttributes import com.intellij.credentialStore.Credentials @@ -26,9 +26,9 @@ object SDCredentials { } var url: String - get() = ApplicationManager.getApplication().getService(SDSettings::class.java).state.url ?: "https://domjudge.iti.kit.edu/main/api/v4" + get() = SDSettings.getInstance().state.url ?: "https://domjudge.iti.kit.edu/main/api/v4" set(value) { - ApplicationManager.getApplication().getService(SDSettings::class.java).state.url = value + SDSettings.getInstance().state.url = value } var teamId: String? diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/SDSettings.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettings.kt similarity index 50% rename from src/main/kotlin/io/gitlab/jfronny/sdom/SDSettings.kt rename to src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettings.kt index 224c283..f18e914 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/SDSettings.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettings.kt @@ -1,5 +1,6 @@ -package io.gitlab.jfronny.sdom +package io.gitlab.jfronny.sdom.settings +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* @Service @@ -7,5 +8,10 @@ import com.intellij.openapi.components.* class SDSettings : SimplePersistentStateComponent(SDState()) { class SDState : BaseState() { var url by string("https://domjudge.iti.kit.edu/main/api/v4") + var pdfMode by enum(PdfMode.INTERNAL_FILE) + } + + companion object { + fun getInstance(): SDSettings = ApplicationManager.getApplication().getService(SDSettings::class.java) } } \ No newline at end of file diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsComponent.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsComponent.kt new file mode 100644 index 0000000..a4ab0fb --- /dev/null +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsComponent.kt @@ -0,0 +1,34 @@ +package io.gitlab.jfronny.sdom.settings + +import com.intellij.openapi.ui.ComboBox +import com.intellij.ui.dsl.builder.panel +import io.gitlab.jfronny.sdom.actions.SDLoginAction +import javax.swing.JPanel + +class SDSettingsComponent { + val mainPanel: JPanel + val pdfModeBox: ComboBox = ComboBox(PdfMode.entries.toTypedArray()) + + init { +// mainPanel = FormBuilder.createFormBuilder() +// .addLabeledComponent("PDF Mode", pdfModeBox) +// .addComponentFillVertically(JPanel(), 0) +// .addComponentFillVertically(ActionManager.getInstance().createActionToolbar( +// "SettingsUI", +// DefaultActionGroup(SDLoginAction("Change Login Credentials")), +// true +// ).component, 0) +// .panel + mainPanel = panel { + row { + label("PDF Mode") + cell(pdfModeBox) + } + row { + button("Change Login Credentials") { + SDLoginAction.perform() + } + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsConfigurable.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsConfigurable.kt new file mode 100644 index 0000000..9f9e65b --- /dev/null +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/settings/SDSettingsConfigurable.kt @@ -0,0 +1,37 @@ +package io.gitlab.jfronny.sdom.settings + +import com.intellij.openapi.options.Configurable +import javax.swing.JComponent + +class SDSettingsConfigurable : Configurable { + private var settingsComponent: SDSettingsComponent? = null + override fun getDisplayName(): String = "S-dom" + override fun getPreferredFocusedComponent(): JComponent? { + return settingsComponent!!.pdfModeBox + } + + override fun createComponent(): JComponent? { + val component = SDSettingsComponent() + settingsComponent = component + return component.mainPanel + } + + override fun isModified(): Boolean { + val state = SDSettings.getInstance().state + return settingsComponent!!.pdfModeBox.selectedItem != state.pdfMode + } + + override fun apply() { + val state = SDSettings.getInstance().state + state.pdfMode = settingsComponent!!.pdfModeBox.selectedItem as PdfMode + } + + override fun reset() { + val state = SDSettings.getInstance().state + settingsComponent!!.pdfModeBox.selectedItem = state.pdfMode + } + + override fun disposeUIResources() { + settingsComponent = null + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/toolwindow/SDToolWindow.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/toolwindow/SDToolWindow.kt index 251d9fa..c10fff5 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/toolwindow/SDToolWindow.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/toolwindow/SDToolWindow.kt @@ -19,16 +19,7 @@ fun loggedOutDialogPanel(): DialogPanel = panel { } row { button("Log In") { - SDLoginAction().actionPerformed( - AnActionEvent( - null, - DataContext.EMPTY_CONTEXT, - ActionPlaces.UNKNOWN, - Presentation(), - ActionManager.getInstance(), - 0 - ) - ) + SDLoginAction.perform() }.align(Align.CENTER) } }.resizableColumn().align(AlignY.CENTER) diff --git a/src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDLoginDialogWrapper.kt b/src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDLoginDialogWrapper.kt index 3009e8f..7ba0234 100644 --- a/src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDLoginDialogWrapper.kt +++ b/src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDLoginDialogWrapper.kt @@ -4,7 +4,7 @@ import com.intellij.openapi.ui.DialogWrapper import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.bindText import com.intellij.ui.dsl.builder.panel -import io.gitlab.jfronny.sdom.SDCredentials +import io.gitlab.jfronny.sdom.settings.SDCredentials import javax.swing.JComponent class SDLoginDialogWrapper : DialogWrapper(true) { diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 14c85ff..ef4cbc9 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -38,6 +38,10 @@ + +