feat: scaffold
This commit is contained in:
commit
8931e85658
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
10
.idea/.gitignore
vendored
Normal file
10
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
/checkstyle-idea.xml
|
||||||
|
/git_toolbox_prj.xml
|
18
.idea/gradle.xml
Normal file
18
.idea/gradle.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="distributionType" value="LOCAL" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleHome" value="/usr/share/java/gradle" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/kotlinc.xml
Normal file
6
.idea/kotlinc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="1.9.22" />
|
||||||
|
</component>
|
||||||
|
</project>
|
25
.idea/misc.xml
Normal file
25
.idea/misc.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="FrameworkDetectionExcludesConfiguration">
|
||||||
|
<file type="web" url="file://$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="MarkdownSettingsMigration">
|
||||||
|
<option name="stateVersion" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||||
|
<entry key="Project Default">
|
||||||
|
<profile-state>
|
||||||
|
<expanded-state>
|
||||||
|
<State />
|
||||||
|
<State>
|
||||||
|
<id>Checkstyle</id>
|
||||||
|
</State>
|
||||||
|
</expanded-state>
|
||||||
|
</profile-state>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
12
.idea/vcs.xml
Normal file
12
.idea/vcs.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CommitMessageInspectionProfile">
|
||||||
|
<profile version="1.0">
|
||||||
|
<inspection_tool class="CommitFormat" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="CommitNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
24
.run/Run IDE with Plugin.run.xml
Normal file
24
.run/Run IDE with Plugin.run.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log"/>
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName"/>
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
|
||||||
|
<option name="externalSystemIdString" value="GRADLE"/>
|
||||||
|
<option name="scriptParameters" value=""/>
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list/>
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="runIde"/>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" value=""/>
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<method v="2"/>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# S-DOM
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [DOMjudge](https://www.domjudge.org/documentation)
|
||||||
|
- [DOMjudge API](https://www.domjudge.org/demoweb/api/doc)
|
||||||
|
- [SimpleCodeTester plugin](https://github.com/Mr-Pine/SimpleCodeTester-IntelliJ-Plugin)
|
||||||
|
- [Example Route](https://domjudge.iti.kit.edu/main/api/v4/contests/5/problems)
|
52
build.gradle.kts
Normal file
52
build.gradle.kts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
id("org.jetbrains.kotlin.jvm") version "1.9.22"
|
||||||
|
id("org.jetbrains.intellij") version "1.17.2"
|
||||||
|
kotlin("plugin.serialization") version "1.9.22"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "io.gitlab.jfronny"
|
||||||
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure Gradle IntelliJ Plugin
|
||||||
|
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
|
||||||
|
intellij {
|
||||||
|
version.set("2023.2.5")
|
||||||
|
type.set("IC") // Target IDE Platform
|
||||||
|
|
||||||
|
plugins.set(listOf(/* Plugin Dependencies */))
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
// Set the JVM compatibility versions
|
||||||
|
withType<JavaCompile> {
|
||||||
|
sourceCompatibility = "17"
|
||||||
|
targetCompatibility = "17"
|
||||||
|
}
|
||||||
|
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||||
|
kotlinOptions.jvmTarget = "17"
|
||||||
|
}
|
||||||
|
|
||||||
|
patchPluginXml {
|
||||||
|
sinceBuild.set("232")
|
||||||
|
untilBuild.set("242.*")
|
||||||
|
}
|
||||||
|
|
||||||
|
signPlugin {
|
||||||
|
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
|
||||||
|
privateKey.set(System.getenv("PRIVATE_KEY"))
|
||||||
|
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
|
||||||
|
}
|
||||||
|
|
||||||
|
publishPlugin {
|
||||||
|
token.set(System.getenv("PUBLISH_TOKEN"))
|
||||||
|
}
|
||||||
|
}
|
6
gradle.properties
Normal file
6
gradle.properties
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
|
||||||
|
kotlin.stdlib.default.dependency=false
|
||||||
|
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
|
||||||
|
org.gradle.configuration-cache=true
|
||||||
|
# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
|
||||||
|
org.gradle.caching=true
|
8
settings.gradle.kts
Normal file
8
settings.gradle.kts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "s-dom"
|
30
src/main/kotlin/io/gitlab/jfronny/sdom/SDCredentials.kt
Normal file
30
src/main/kotlin/io/gitlab/jfronny/sdom/SDCredentials.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package io.gitlab.jfronny.sdom
|
||||||
|
|
||||||
|
import com.intellij.credentialStore.CredentialAttributes
|
||||||
|
import com.intellij.credentialStore.Credentials
|
||||||
|
import com.intellij.credentialStore.generateServiceName
|
||||||
|
import com.intellij.ide.passwordSafe.PasswordSafe
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
|
||||||
|
object SDCredentials {
|
||||||
|
private fun createCredentialAttributes(): CredentialAttributes {
|
||||||
|
return CredentialAttributes(generateServiceName("s-dom", "httpAuth"))
|
||||||
|
}
|
||||||
|
|
||||||
|
var credentials: Pair<String?, String?>
|
||||||
|
get() = PasswordSafe.instance.get(createCredentialAttributes())
|
||||||
|
.run { this?.userName to this?.getPasswordAsString() }
|
||||||
|
set(value) {
|
||||||
|
PasswordSafe.instance[createCredentialAttributes()] = Credentials(value.first, value.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logOut() {
|
||||||
|
PasswordSafe.instance.set(createCredentialAttributes(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
var url: String
|
||||||
|
get() = ApplicationManager.getApplication().getService(SDSettings::class.java).state.url ?: "https://domjudge.iti.kit.edu/main/api"
|
||||||
|
set(value) {
|
||||||
|
ApplicationManager.getApplication().getService(SDSettings::class.java).state.url = value
|
||||||
|
}
|
||||||
|
}
|
11
src/main/kotlin/io/gitlab/jfronny/sdom/SDSettings.kt
Normal file
11
src/main/kotlin/io/gitlab/jfronny/sdom/SDSettings.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package io.gitlab.jfronny.sdom
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.*
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@State(name = "S-DOM", storages = [Storage("s-dom.xml")])
|
||||||
|
class SDSettings : SimplePersistentStateComponent<SDSettings.SDState>(SDState()) {
|
||||||
|
class SDState : BaseState() {
|
||||||
|
var url by string("https://domjudge.iti.kit.edu/main/api")
|
||||||
|
}
|
||||||
|
}
|
66
src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt
Normal file
66
src/main/kotlin/io/gitlab/jfronny/sdom/SDom.kt
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package io.gitlab.jfronny.sdom
|
||||||
|
|
||||||
|
import com.intellij.ide.util.PropertiesComponent
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.diagnostic.LogLevel
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import io.gitlab.jfronny.sdom.model.SDLoginResult
|
||||||
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.call.*
|
||||||
|
import io.ktor.client.engine.cio.*
|
||||||
|
import io.ktor.client.plugins.auth.*
|
||||||
|
import io.ktor.client.plugins.auth.providers.*
|
||||||
|
import io.ktor.client.plugins.contentnegotiation.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
object SDom {
|
||||||
|
private val logger = Logger.getInstance(SDom.javaClass).apply { setLevel(LogLevel.DEBUG) }
|
||||||
|
private var propertiesComponent: PropertiesComponent? = null
|
||||||
|
|
||||||
|
private val client = HttpClient(CIO) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json(Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
install(Auth) {
|
||||||
|
basic {
|
||||||
|
credentials {
|
||||||
|
BasicAuthCredentials(SDCredentials.credentials.first ?: "", SDCredentials.credentials.second ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val loginListeners: MutableList<() -> Unit> = mutableListOf() //TODO add listener for refreshing tasks
|
||||||
|
private val logoutListeners: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
|
fun registerLoginListener(listener: () -> Unit) {
|
||||||
|
loginListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerLogoutListener(listener: () -> Unit) {
|
||||||
|
logoutListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun login(username: String, password: String, url: String) {
|
||||||
|
val fixedApi = url.trimEnd('/') + "/v4/"
|
||||||
|
val result: SDLoginResult = client.get(url = Url(fixedApi + "user")).body()
|
||||||
|
if (!result.enabled) throw Exception("User is not enabled")
|
||||||
|
SDCredentials.credentials = Pair(username, password)
|
||||||
|
SDCredentials.url = fixedApi
|
||||||
|
|
||||||
|
loginListeners.forEach { ApplicationManager.getApplication().invokeLater(it) }
|
||||||
|
logger.debug("Logged in as $username")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logout() {
|
||||||
|
SDCredentials.logOut()
|
||||||
|
logoutListeners.forEach { ApplicationManager.getApplication().invokeLater(it) }
|
||||||
|
}
|
||||||
|
val loggedIn: Boolean
|
||||||
|
get() = SDCredentials.credentials.first != null && SDCredentials.credentials.second != null
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
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 io.gitlab.jfronny.sdom.SDom
|
||||||
|
import io.gitlab.jfronny.sdom.ui.SDLoginDialogWrapper
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class SDLoginAction(text: String) : NotificationAction(text) {
|
||||||
|
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
|
||||||
|
|
||||||
|
constructor() : this("")
|
||||||
|
|
||||||
|
override fun actionPerformed(e: AnActionEvent, notification: Notification) = actionPerformed(e)
|
||||||
|
|
||||||
|
override fun actionPerformed(e: AnActionEvent) {
|
||||||
|
val dialogWrapper = SDLoginDialogWrapper()
|
||||||
|
|
||||||
|
if (dialogWrapper.showAndGet()) {
|
||||||
|
CoroutineScope(Job() + Dispatchers.IO).launch {
|
||||||
|
SDom.login(username = dialogWrapper.username, password = dialogWrapper.password, url = dialogWrapper.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.actions
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
|
import com.intellij.openapi.project.DumbAwareAction
|
||||||
|
import io.gitlab.jfronny.sdom.SDom
|
||||||
|
|
||||||
|
class SDLogoutAction : DumbAwareAction() {
|
||||||
|
override fun actionPerformed(e: AnActionEvent) = SDom.logout()
|
||||||
|
|
||||||
|
override fun update(e: AnActionEvent) {
|
||||||
|
e.presentation.isVisible = SDom.loggedIn
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.model
|
||||||
|
|
||||||
|
import kotlinx.datetime.LocalDateTime
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SDLoginResult(
|
||||||
|
@SerialName("last_login_time") val lastLoginTime: LocalDateTime,
|
||||||
|
@SerialName("last_api_login_time") val lastApiLoginTime: LocalDateTime,
|
||||||
|
@SerialName("first_login_time") val firstLoginTime: LocalDateTime,
|
||||||
|
val team: String,
|
||||||
|
@SerialName("team_id") val teamId: Int,
|
||||||
|
val roles: List<String>,
|
||||||
|
val type: String,
|
||||||
|
val id: String,
|
||||||
|
val username: String,
|
||||||
|
val name: String,
|
||||||
|
val email: String,
|
||||||
|
@SerialName("last_ip") val lastIp: String,
|
||||||
|
val ip: String,
|
||||||
|
val enabled: Boolean
|
||||||
|
)
|
@ -0,0 +1,36 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.toolwindow
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
|
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.actionSystem.Presentation
|
||||||
|
import com.intellij.openapi.ui.DialogPanel
|
||||||
|
import com.intellij.ui.dsl.builder.Align
|
||||||
|
import com.intellij.ui.dsl.builder.AlignY
|
||||||
|
import com.intellij.ui.dsl.builder.panel
|
||||||
|
import io.gitlab.jfronny.sdom.actions.SDLoginAction
|
||||||
|
|
||||||
|
fun SDToolWindow(): DialogPanel = panel {
|
||||||
|
row {
|
||||||
|
panel {
|
||||||
|
row {
|
||||||
|
label("You are not logged in. Please log in to use this tool.").align(Align.CENTER)
|
||||||
|
}
|
||||||
|
row {
|
||||||
|
button("Log In") {
|
||||||
|
SDLoginAction().actionPerformed(
|
||||||
|
AnActionEvent(
|
||||||
|
null,
|
||||||
|
DataContext.EMPTY_CONTEXT,
|
||||||
|
ActionPlaces.UNKNOWN,
|
||||||
|
Presentation(),
|
||||||
|
ActionManager.getInstance(),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}.align(Align.CENTER)
|
||||||
|
}
|
||||||
|
}.resizableColumn().align(AlignY.CENTER)
|
||||||
|
}.resizableRow()
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.toolwindow
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.DumbAware
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.wm.ToolWindow
|
||||||
|
import com.intellij.openapi.wm.ToolWindowFactory
|
||||||
|
import io.gitlab.jfronny.sdom.SDom
|
||||||
|
import io.gitlab.jfronny.sdom.ui.SDSubmitPanel
|
||||||
|
|
||||||
|
class SDToolWindowFactory : ToolWindowFactory, DumbAware {
|
||||||
|
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
|
||||||
|
val contentManager = toolWindow.contentManager
|
||||||
|
val loggedOutContent = contentManager.factory.createContent(loggedOutDialogPanel(), null, false).apply {
|
||||||
|
isCloseable = false
|
||||||
|
}
|
||||||
|
val submitContent = contentManager.factory.createContent(SDSubmitPanel(), "Submit", false).apply {
|
||||||
|
isCloseable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showSubmitContent() {
|
||||||
|
contentManager.addContent(submitContent)
|
||||||
|
contentManager.removeContent(loggedOutContent, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showLoggedOutContent() {
|
||||||
|
contentManager.removeContent(submitContent, true)
|
||||||
|
contentManager.addContent(loggedOutContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showResultContent() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
SDom.registerLoginListener(::showSubmitContent)
|
||||||
|
SDom.registerLogoutListener(::showLoggedOutContent)
|
||||||
|
SDom.registerResultFlowListener(::showResultContent)
|
||||||
|
|
||||||
|
if (SDom.loggedIn) {
|
||||||
|
showSubmitContent()
|
||||||
|
} else {
|
||||||
|
contentManager.addContent(loggedOutContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDActionToolBar.kt
Normal file
25
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDActionToolBar.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.ui
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionGroup
|
||||||
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import javax.swing.Box
|
||||||
|
import javax.swing.JComponent
|
||||||
|
|
||||||
|
class SDActionToolBar(orientation: ToolBarOrientation, place: @NonNls String = "???") {
|
||||||
|
private val actionGroup = ActionManager.getInstance()
|
||||||
|
.getAction("io.gitlab.jfronny.sdom.actions.SDToolbarActions") as ActionGroup
|
||||||
|
|
||||||
|
private val toolbar = ActionManager.getInstance().createActionToolbar(place, actionGroup, orientation.value)
|
||||||
|
|
||||||
|
fun setTargetComponent(component: JComponent) {
|
||||||
|
toolbar.targetComponent = component
|
||||||
|
}
|
||||||
|
|
||||||
|
val component: Box
|
||||||
|
get() = Box.createHorizontalBox().apply { add(toolbar.component) }
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ToolBarOrientation(val value: Boolean) {
|
||||||
|
HORIZONTAL(true), VERTICAL(false)
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.ui
|
||||||
|
|
||||||
|
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 javax.swing.JComponent
|
||||||
|
|
||||||
|
class SDLoginDialogWrapper : DialogWrapper(true) {
|
||||||
|
var username = ""
|
||||||
|
var password = ""
|
||||||
|
var url = ""
|
||||||
|
|
||||||
|
init {
|
||||||
|
title = "Log in to DOMjudge"
|
||||||
|
url = SDCredentials.url
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createCenterPanel(): JComponent = panel {
|
||||||
|
row {
|
||||||
|
label("Username")
|
||||||
|
textField().align(AlignX.FILL).bindText(this@SDLoginDialogWrapper::username)
|
||||||
|
}
|
||||||
|
row {
|
||||||
|
label("Password")
|
||||||
|
passwordField().align(AlignX.FILL).bindText(this@SDLoginDialogWrapper::password)
|
||||||
|
}
|
||||||
|
row {
|
||||||
|
label("API URL")
|
||||||
|
textField().align(AlignX.FILL).bindText(this@SDLoginDialogWrapper::url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDResultPanel.kt
Normal file
24
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDResultPanel.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.ui
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.ui.ComponentContainer
|
||||||
|
import io.gitlab.jfronny.sdom.model.SDResult
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import javax.swing.JComponent
|
||||||
|
|
||||||
|
class SDResultPanel(
|
||||||
|
val project: Project,
|
||||||
|
resultFlow: Flow<Result<SDResult>>
|
||||||
|
) : ComponentContainer {
|
||||||
|
override fun dispose() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getComponent(): JComponent {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPreferredFocusableComponent(): JComponent {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
17
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDSubmitPanel.kt
Normal file
17
src/main/kotlin/io/gitlab/jfronny/sdom/ui/SDSubmitPanel.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.ui
|
||||||
|
|
||||||
|
import com.intellij.ui.components.JBLabel
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import javax.swing.JPanel
|
||||||
|
|
||||||
|
class SDSubmitPanel : JPanel(BorderLayout()) {
|
||||||
|
init {
|
||||||
|
val label = JBLabel("Nothing to see here (yet)")
|
||||||
|
val toolWindowPanel = SDToolWindowPanel(
|
||||||
|
topComponent = SDActionToolBar(ToolBarOrientation.HORIZONTAL).apply { setTargetComponent(label) }.component,
|
||||||
|
mainComponent = label
|
||||||
|
)
|
||||||
|
add(toolWindowPanel.getPanel())
|
||||||
|
isVisible = true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.gitlab.jfronny.sdom.ui
|
||||||
|
|
||||||
|
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import javax.swing.JComponent
|
||||||
|
|
||||||
|
class SDToolWindowPanel(
|
||||||
|
private val topComponent: JComponent? = null,
|
||||||
|
private val leftComplement: JComponent? = null,
|
||||||
|
private val mainComponent: JComponent? = null,
|
||||||
|
private val rightComplement: JComponent? = null
|
||||||
|
) {
|
||||||
|
private val basePanel = BorderLayoutPanel(1, 1).apply {
|
||||||
|
mainComponent?.let { add(it, BorderLayout.CENTER) }
|
||||||
|
topComponent?.let { add(it, BorderLayout.NORTH) }
|
||||||
|
leftComplement?.let { add(it, BorderLayout.WEST) }
|
||||||
|
rightComplement?.let { add(it, BorderLayout.EAST) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPanel() = basePanel
|
||||||
|
}
|
32
src/main/resources/META-INF/plugin.xml
Normal file
32
src/main/resources/META-INF/plugin.xml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
|
||||||
|
<idea-plugin>
|
||||||
|
<!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. -->
|
||||||
|
<id>io.gitlab.jfronny.s-dom</id>
|
||||||
|
|
||||||
|
<!-- Public plugin name should be written in Title Case.
|
||||||
|
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name -->
|
||||||
|
<name>S-dom</name>
|
||||||
|
|
||||||
|
<!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
|
||||||
|
<vendor email="projects.contact@frohnmeyer-wds.de" url="https://jfronny.gitlab.io">JFronny</vendor>
|
||||||
|
|
||||||
|
<!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
|
||||||
|
Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
|
||||||
|
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
|
||||||
|
<description><![CDATA[
|
||||||
|
Simple plugin to upload potential solutions to a DOMjudge instance.<br>
|
||||||
|
Intended mostly for use in the context of the KITs "Basispraktikum zum ICPC-Programmierwettbewerb" course.<br>
|
||||||
|
]]></description>
|
||||||
|
|
||||||
|
<!-- Product and plugin compatibility requirements.
|
||||||
|
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html -->
|
||||||
|
<depends>com.intellij.modules.platform</depends>
|
||||||
|
|
||||||
|
<!-- Extension points defined by the plugin.
|
||||||
|
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html -->
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<toolWindow factoryClass="io.gitlab.jfronny.sdom.toolwindow.SDToolWindowFactory"
|
||||||
|
id="S-DOM" anchor="bottom" canCloseContents="true" icon="io.gitlab.jfronny.sdom.icons.ToolWindow" />
|
||||||
|
<notificationGroup id="sdom.notifications" displayType="BALLOON" />
|
||||||
|
</extensions>
|
||||||
|
</idea-plugin>
|
12
src/main/resources/META-INF/pluginIcon.svg
Normal file
12
src/main/resources/META-INF/pluginIcon.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M32.0845 7.94025V4H24.0203V7.9896H16.029V4H7.91553V7.94025H4V36H16.0044V32.0045C16.0058 30.9457 16.4274 29.9308 17.1766 29.1826C17.9258 28.4345 18.9412 28.0143 20 28.0143C21.0588 28.0143 22.0743 28.4345 22.8234 29.1826C23.5726 29.9308 23.9942 30.9457 23.9956 32.0045V36H36V7.94025H32.0845Z"
|
||||||
|
fill="url(#paint0_linear)"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear" x1="2.94192" y1="4.89955" x2="37.7772" y2="39.7345"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.15937" stop-color="#3BEA62"/>
|
||||||
|
<stop offset="0.5404" stop-color="#3C99CC"/>
|
||||||
|
<stop offset="0.93739" stop-color="#6B57FF"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 818 B |
Loading…
Reference in New Issue
Block a user