diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fd5c32..a4b4359 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Library Test +name: Application Test on: push: pull_request: diff --git a/README.md b/README.md index 960eacc..9f81c7b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ [![CodeFactor](https://www.codefactor.io/repository/github/spbu-coding-2024/graphs-team-3/badge)](https://www.codefactor.io/repository/github/spbu-coding-2024/graphs-team-3) + +![example workflow](https://github.com/spbu-coding-2024/graphs-team-3/actions/workflows/build.yml/badge.svg) ![Kotlin](https://img.shields.io/badge/Kotlin-2.1.10-blue.svg) ![Gradle](https://img.shields.io/badge/Gradle-8.13-brightgreen.svg) ![Java](https://img.shields.io/badge/Java-21-brightgreen.svg) diff --git a/app/src/main/kotlin/model/algo/fordBellman/FordBellman.kt b/app/src/main/kotlin/model/algo/FordBellman.kt similarity index 99% rename from app/src/main/kotlin/model/algo/fordBellman/FordBellman.kt rename to app/src/main/kotlin/model/algo/FordBellman.kt index 77887b4..7620c4e 100644 --- a/app/src/main/kotlin/model/algo/fordBellman/FordBellman.kt +++ b/app/src/main/kotlin/model/algo/FordBellman.kt @@ -1,4 +1,4 @@ -package model.algo.fordBellman +package model.algo import model.graph.Edge import model.graph.Graph diff --git a/app/src/main/kotlin/model/algo/findBridges/findBridges.kt b/app/src/main/kotlin/model/algo/findBridges.kt similarity index 98% rename from app/src/main/kotlin/model/algo/findBridges/findBridges.kt rename to app/src/main/kotlin/model/algo/findBridges.kt index acf2152..3c3bde3 100644 --- a/app/src/main/kotlin/model/algo/findBridges/findBridges.kt +++ b/app/src/main/kotlin/model/algo/findBridges.kt @@ -1,4 +1,4 @@ -package model.algo.findBridges +package model.algo import model.graph.Edge import model.graph.Graph diff --git a/app/src/main/kotlin/model/algo/findCommunities.kt b/app/src/main/kotlin/model/algo/findCommunities.kt index 53ef521..84e28e8 100644 --- a/app/src/main/kotlin/model/algo/findCommunities.kt +++ b/app/src/main/kotlin/model/algo/findCommunities.kt @@ -4,14 +4,18 @@ import model.graph.Graph import model.graph.Vertex import org.jetbrains.research.ictl.louvain.getPartition -fun findCommunities(graph: Graph, depth: Int = 2): Map> { - val links = graph.edges.map { - EdgeLink( - from = it.vertices.first.id, - to = it.vertices.second.id, - weight = it.weight.toDouble() - ) - } +fun findCommunities( + graph: Graph, + depth: Int = 2, +): Map> { + val links = + graph.edges.map { + EdgeLink( + from = it.vertices.first.id, + to = it.vertices.second.id, + weight = it.weight.toDouble(), + ) + } val partition = getPartition(links, depth).toMutableMap() @@ -28,6 +32,6 @@ fun findCommunities(graph: Graph, depth: Int = 2): Map> { return partition.entries .groupBy( keySelector = { it.value }, - valueTransform= { idToVertex.getValue(it.key) } + valueTransform = { idToVertex.getValue(it.key) }, ) } diff --git a/app/src/main/kotlin/model/algo/findMST.kt b/app/src/main/kotlin/model/algo/findMST.kt index 77439dc..7215741 100644 --- a/app/src/main/kotlin/model/algo/findMST.kt +++ b/app/src/main/kotlin/model/algo/findMST.kt @@ -1,7 +1,7 @@ package model.algo -import model.graph.Graph import model.graph.Edge +import model.graph.Graph fun findMST(graph: Graph): Set { require(!graph.isDirected) { "MST is only implemented for undirected graphs" } @@ -10,9 +10,10 @@ fun findMST(graph: Graph): Set { val mstEdges = mutableSetOf() val verticesList = graph.vertices.toList() - val idToIndex = verticesList - .mapIndexed { index, vertex -> vertex.id to index } - .toMap() + val idToIndex = + verticesList + .mapIndexed { index, vertex -> vertex.id to index } + .toMap() val parents = IntArray(verticesList.size) { -1 } @@ -22,7 +23,10 @@ fun findMST(graph: Graph): Set { return parents[vertexId] } - fun unionSets(firstId: Int, secondId: Int) { + fun unionSets( + firstId: Int, + secondId: Int, + ) { val rootFirst = findRoot(firstId) val rootSecond = findRoot(secondId) if (rootFirst == rootSecond) return diff --git a/app/src/main/kotlin/model/algo/findSCC.kt b/app/src/main/kotlin/model/algo/findSCC.kt index bd685a8..6fc272d 100644 --- a/app/src/main/kotlin/model/algo/findSCC.kt +++ b/app/src/main/kotlin/model/algo/findSCC.kt @@ -21,7 +21,7 @@ fun findSCC(graph: Graph): Set> { fun dfs(vertex: Vertex) { visited += vertex - for (neighbor in adjacencyList[vertex]?: throw IllegalStateException()) { + for (neighbor in adjacencyList[vertex] ?: throw IllegalStateException()) { if (neighbor !in visited) dfs(neighbor) } stack.addFirst(vertex) @@ -30,10 +30,14 @@ fun findSCC(graph: Graph): Set> { for (vertex in adjacencyList.keys) if (vertex !in visited) dfs(vertex) visited.clear() - fun findComponents(vertex: Vertex, component: MutableSet) { + + fun findComponents( + vertex: Vertex, + component: MutableSet, + ) { visited += vertex component += vertex - for (neighbor in revAdjacencyList[vertex]?: throw IllegalStateException()) { + for (neighbor in revAdjacencyList[vertex] ?: throw IllegalStateException()) { if (neighbor !in visited) findComponents(neighbor, component) } } diff --git a/app/src/main/kotlin/model/io/sqlite/sqliteRepository.kt b/app/src/main/kotlin/model/io/sqlite/sqliteRepository.kt index 4a6cf54..875e00e 100644 --- a/app/src/main/kotlin/model/io/sqlite/sqliteRepository.kt +++ b/app/src/main/kotlin/model/io/sqlite/sqliteRepository.kt @@ -3,11 +3,12 @@ package model.io.sqlite import model.graph.* import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.transactions.transaction -class SqliteRepository(dbPath: String = "../graphs.db") { - +class SqliteRepository( + dbPath: String = "../graphs.db", +) { object Graphs : IntIdTable("graphs") { val name = varchar("name", 52) val isDirected = bool("isDirected") @@ -27,10 +28,11 @@ class SqliteRepository(dbPath: String = "../graphs.db") { val weight = long("weight") } - private val db: Database = Database.connect( - url = "jdbc:sqlite:$dbPath?foreign_keys=ON", - driver = "org.sqlite.JDBC" - ) + private val db: Database = + Database.connect( + url = "jdbc:sqlite:$dbPath?foreign_keys=ON", + driver = "org.sqlite.JDBC", + ) init { transaction(db) { @@ -38,60 +40,73 @@ class SqliteRepository(dbPath: String = "../graphs.db") { } } - fun save(g: Graph, name: String? = null): Int = transaction(db) { - val gId = Graphs.insertAndGetId { - it[this.name] = name ?: "Graph_${System.currentTimeMillis()}" - it[this.isDirected] = g.isDirected - }.value + fun save( + g: Graph, + name: String? = null, + ): Int = + transaction(db) { + val gId = + Graphs + .insertAndGetId { + it[this.name] = name ?: "Graph_${System.currentTimeMillis()}" + it[this.isDirected] = g.isDirected + }.value + + Vertices.batchInsert(g.vertices) { vertex -> + this[Vertices.graph] = gId + this[Vertices.label] = vertex.label + this[Vertices.origId] = vertex.id + } - Vertices.batchInsert(g.vertices) { vertex -> - this[Vertices.graph] = gId - this[Vertices.label] = vertex.label - this[Vertices.origId] = vertex.id - } + Edges.batchInsert(g.edges) { edge -> + this[Edges.graph] = gId + this[Edges.fromId] = edge.vertices.first.id + this[Edges.toId] = edge.vertices.second.id + this[Edges.weight] = edge.weight + this[Edges.origId] = edge.id + } - Edges.batchInsert(g.edges) { edge -> - this[Edges.graph] = gId - this[Edges.fromId] = edge.vertices.first.id - this[Edges.toId] = edge.vertices.second.id - this[Edges.weight] = edge.weight - this[Edges.origId] = edge.id + gId } - gId - } - - fun delete(gId: Int) = transaction(db) { - Graphs.deleteWhere { id eq gId } - } - - fun read(gId: Int): Graph = transaction(db) { - val directed = Graphs - .selectAll() - .where { Graphs.id eq gId } - .single() - .let { it[Graphs.isDirected] } - - val g = Graph(isDirected = directed) - - Vertices - .selectAll() - .where { Vertices.graph eq gId } - .forEach { row -> - g.addVertex(row[Vertices.origId], row[Vertices.label]) - } - - Edges - .selectAll() - .where { Edges.graph eq gId } - .forEach { row -> - g.addEdge(row[Edges.fromId], row[Edges.toId], row[Edges.weight]) - } + fun delete(gId: Int) = + transaction(db) { + Graphs.deleteWhere { id eq gId } + } - g - } + fun read(gId: Int): Graph = + transaction(db) { + val directed = + Graphs + .selectAll() + .where { Graphs.id eq gId } + .single() + .let { it[Graphs.isDirected] } + + val g = Graph(isDirected = directed) + + Vertices + .selectAll() + .where { Vertices.graph eq gId } + .forEach { row -> + g.addVertex(row[Vertices.origId], row[Vertices.label]) + } + + Edges + .selectAll() + .where { Edges.graph eq gId } + .forEach { row -> + g.addEdge(row[Edges.fromId], row[Edges.toId], row[Edges.weight]) + } + + g + } - fun update(gId: Int, g: Graph, newName: String? = null) = transaction(db) { + fun update( + gId: Int, + g: Graph, + newName: String? = null, + ) = transaction(db) { Graphs.update({ Graphs.id eq gId }) { it[isDirected] = g.isDirected if (newName != null) it[name] = newName @@ -115,14 +130,19 @@ class SqliteRepository(dbPath: String = "../graphs.db") { } } - fun listGraphs(filter: String = ""): List> = transaction(db) { - val q = if (filter.isBlank()) - Graphs.selectAll() - else - Graphs.selectAll() - .where { Graphs.name like "%$filter%" } - - q.orderBy(Graphs.name to SortOrder.ASC) - .map { it[Graphs.id].value to it[Graphs.name] } - } + fun listGraphs(filter: String = ""): List> = + transaction(db) { + val q = + if (filter.isBlank()) { + Graphs.selectAll() + } else { + Graphs + .selectAll() + .where { Graphs.name like "%$filter%" } + } + + q + .orderBy(Graphs.name to SortOrder.ASC) + .map { it[Graphs.id].value to it[Graphs.name] } + } } diff --git a/app/src/main/kotlin/view/dialogs/SqliteDeleteDialog.kt b/app/src/main/kotlin/view/dialogs/SqliteDeleteDialog.kt index d0f41e9..9c7108a 100644 --- a/app/src/main/kotlin/view/dialogs/SqliteDeleteDialog.kt +++ b/app/src/main/kotlin/view/dialogs/SqliteDeleteDialog.kt @@ -6,11 +6,11 @@ import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Warning import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.unit.dp -import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.unit.dp import viewmodel.colors.ColorTheme @Composable @@ -32,19 +32,19 @@ fun SqliteDeleteDialog( Text("Delete \"$graphName\"?") } }, - text = { Text("This action cannot be undone")}, + text = { Text("This action cannot be undone") }, buttons = { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { TextButton( modifier = Modifier.padding(end = 16.dp), onClick = { open = false onDismiss() - } + }, ) { Text("Cancel", color = ColorTheme.TextColor) } Button( modifier = Modifier.padding(end = 16.dp), @@ -52,11 +52,11 @@ fun SqliteDeleteDialog( onConfirm() open = false }, - colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor) + colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor), ) { Text("Delete") } } }, - modifier = Modifier.clip(RoundedCornerShape(percent = 5)) + modifier = Modifier.clip(RoundedCornerShape(percent = 5)), ) } } diff --git a/app/src/main/kotlin/view/dialogs/SqliteOverwriteDialog.kt b/app/src/main/kotlin/view/dialogs/SqliteOverwriteDialog.kt index 619d8a1..64e7bf2 100644 --- a/app/src/main/kotlin/view/dialogs/SqliteOverwriteDialog.kt +++ b/app/src/main/kotlin/view/dialogs/SqliteOverwriteDialog.kt @@ -33,19 +33,20 @@ fun OverwriteDialog( } }, text = { - Text("Graph \"$graphName\" will be overwritten. Continue?") }, + Text("Graph \"$graphName\" will be overwritten. Continue?") + }, buttons = { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { TextButton( modifier = Modifier.padding(end = 16.dp), onClick = { open = false onDismiss() - } + }, ) { Text("Cancel", color = ColorTheme.TextColor) } Button( modifier = Modifier.padding(end = 16.dp), @@ -53,13 +54,14 @@ fun OverwriteDialog( onConfirm() open = false }, - colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor) + colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor), ) { Text("Continue") } } }, - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(percent = 5)) + modifier = + Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(percent = 5)), ) } } diff --git a/app/src/main/kotlin/view/io/SqliteSaveView.kt b/app/src/main/kotlin/view/io/SqliteSaveView.kt index 9830146..8ecde9f 100644 --- a/app/src/main/kotlin/view/io/SqliteSaveView.kt +++ b/app/src/main/kotlin/view/io/SqliteSaveView.kt @@ -13,8 +13,8 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import model.graph.Graph import model.io.sqlite.SqliteRepository -import view.dialogs.exceptionView import view.dialogs.OverwriteDialog +import view.dialogs.exceptionView import viewmodel.colors.ColorTheme import viewmodel.screens.SqliteSaveViewModel @@ -41,31 +41,34 @@ fun sqliteSaveView( title = { Text(text = "Create name for the graph") }, buttons = { Column( - modifier = Modifier - .padding(8.dp) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally + modifier = + Modifier + .padding(8.dp) + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, ) { OutlinedTextField( value = nameState.value, onValueChange = vm::onNameChange, label = { Text(text = "Name") }, colors = TextFieldDefaults.outlinedTextFieldColors(backgroundColor = ColorTheme.TextFieldColor), - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(8.dp)) LazyColumn( - modifier = Modifier - .heightIn(max = 300.dp) - .fillMaxWidth() + modifier = + Modifier + .heightIn(max = 300.dp) + .fillMaxWidth(), ) { items(vm.graphs) { (_, name) -> Row( - modifier = Modifier - .fillMaxWidth() - .padding(6.dp) - .clickable { vm.onGraphClicked(name) }, - horizontalArrangement = Arrangement.SpaceBetween + modifier = + Modifier + .fillMaxWidth() + .padding(6.dp) + .clickable { vm.onGraphClicked(name) }, + horizontalArrangement = Arrangement.SpaceBetween, ) { Text(text = name) } @@ -74,16 +77,19 @@ fun sqliteSaveView( Spacer(Modifier.height(8.dp)) Row( horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { Button( onClick = { vm.chooseFile() }, - colors = ButtonDefaults.buttonColors(ColorTheme.ButtonColor) + colors = ButtonDefaults.buttonColors(ColorTheme.ButtonColor), ) { Text(text = "Choose file") } Row { Button( - onClick = { open = false; onDismiss() }, - colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor) + onClick = { + open = false + onDismiss() + }, + colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor), ) { Text(text = "Cancel") } Spacer(Modifier.width(8.dp)) Button( @@ -93,13 +99,13 @@ fun sqliteSaveView( onDismiss() } }, - colors = ButtonDefaults.buttonColors(ColorTheme.ConfirmColor) + colors = ButtonDefaults.buttonColors(ColorTheme.ConfirmColor), ) { Text(text = "Save") } } } } }, - modifier = Modifier.clip(RoundedCornerShape(percent = 5)) + modifier = Modifier.clip(RoundedCornerShape(percent = 5)), ) } @@ -111,11 +117,11 @@ fun sqliteSaveView( open = false onDismiss() }, - onDismiss = vm::cancelOverwrite + onDismiss = vm::cancelOverwrite, ) } if (exceptionDialog.value) { exceptionView(message.value) { vm.setExceptionDialog(false) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/view/io/SqliteView.kt b/app/src/main/kotlin/view/io/SqliteView.kt index 369ce7c..0ab3f40 100644 --- a/app/src/main/kotlin/view/io/SqliteView.kt +++ b/app/src/main/kotlin/view/io/SqliteView.kt @@ -15,8 +15,8 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import model.graph.Graph import model.io.sqlite.SqliteRepository -import view.dialogs.exceptionView import view.dialogs.SqliteDeleteDialog +import view.dialogs.exceptionView import viewmodel.colors.ColorTheme import viewmodel.screens.SqliteViewModel @@ -43,39 +43,42 @@ fun sqliteView( title = { Text(text = "Choose the graph") }, buttons = { Column( - modifier = Modifier - .padding(8.dp) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally + modifier = + Modifier + .padding(8.dp) + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, ) { OutlinedTextField( value = vm.filter, onValueChange = vm::onFilterChange, label = { Text(text = "Search") }, colors = TextFieldDefaults.outlinedTextFieldColors(backgroundColor = ColorTheme.TextFieldColor), - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) Spacer(Modifier.height(8.dp)) LazyColumn( - modifier = Modifier - .heightIn(max = 300.dp) - .fillMaxWidth() + modifier = + Modifier + .heightIn(max = 300.dp) + .fillMaxWidth(), ) { items(vm.graphs) { (id, name) -> Row( - modifier = Modifier - .fillMaxWidth() - .padding(6.dp) - .clickable { - onGraphChosen(vm.openGraph(id), id) - open = false - }, - horizontalArrangement = Arrangement.SpaceBetween + modifier = + Modifier + .fillMaxWidth() + .padding(6.dp) + .clickable { + onGraphChosen(vm.openGraph(id), id) + open = false + }, + horizontalArrangement = Arrangement.SpaceBetween, ) { Text(text = name) IconButton( onClick = { vm.startDelete(id, name) }, - modifier = Modifier.size(20.dp) + modifier = Modifier.size(20.dp), ) { Icon(Icons.Default.Delete, "Delete") } @@ -85,20 +88,23 @@ fun sqliteView( Spacer(Modifier.height(8.dp)) Row( horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { Button( onClick = { vm.chooseFile() }, - colors = ButtonDefaults.buttonColors(ColorTheme.ButtonColor) + colors = ButtonDefaults.buttonColors(ColorTheme.ButtonColor), ) { Text(text = "Choose file") } Button( - onClick = { open = false; onDismiss() }, - colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor) + onClick = { + open = false + onDismiss() + }, + colors = ButtonDefaults.buttonColors(ColorTheme.rejectColor), ) { Text(text = "Cancel") } } } }, - modifier = Modifier.clip(RoundedCornerShape(percent = 5)) + modifier = Modifier.clip(RoundedCornerShape(percent = 5)), ) } @@ -106,7 +112,7 @@ fun sqliteView( SqliteDeleteDialog( graphName = toDelete.value?.second.orEmpty(), onConfirm = vm::confirmDelete, - onDismiss = vm::cancelDelete + onDismiss = vm::cancelDelete, ) } diff --git a/app/src/main/kotlin/view/screens/MainScreenView.kt b/app/src/main/kotlin/view/screens/MainScreenView.kt index e2ce575..f5cf37d 100644 --- a/app/src/main/kotlin/view/screens/MainScreenView.kt +++ b/app/src/main/kotlin/view/screens/MainScreenView.kt @@ -20,9 +20,9 @@ import view.dialogs.FordBellmanDialog import view.dialogs.exceptionView import view.graph.GraphView import view.io.neo4jView +import view.io.sqliteSaveView import viewmodel.colors.ColorTheme import viewmodel.screens.MainScreenViewModel -import view.io.sqliteSaveView @Composable fun MainScreen(viewModel: MainScreenViewModel) { @@ -55,7 +55,7 @@ fun MainScreen(viewModel: MainScreenViewModel) { DropdownMenuItem(onClick = { viewModel.selectStorage(Storage.Neo4j) }) { Text("Save to Neo4j") } - DropdownMenuItem(onClick = {viewModel.selectStorage(Storage.SQLite)}) { + DropdownMenuItem(onClick = { viewModel.selectStorage(Storage.SQLite) }) { Text("Save to SQLite") } } diff --git a/app/src/main/kotlin/viewmodel/graph/GraphViewModel.kt b/app/src/main/kotlin/viewmodel/graph/GraphViewModel.kt index 3eb05b9..b81bf4d 100644 --- a/app/src/main/kotlin/viewmodel/graph/GraphViewModel.kt +++ b/app/src/main/kotlin/viewmodel/graph/GraphViewModel.kt @@ -2,8 +2,8 @@ package viewmodel.graph import androidx.compose.runtime.State import androidx.compose.ui.unit.dp -import model.algo.findBridges.findBridges -import model.algo.fordBellman.fordBellman +import model.algo.findBridges +import model.algo.fordBellman import model.graph.Graph import model.graph.Vertex import viewmodel.colors.ColorTheme diff --git a/app/src/main/kotlin/viewmodel/screens/MainScreenViewModel.kt b/app/src/main/kotlin/viewmodel/screens/MainScreenViewModel.kt index c1d1326..1124ed3 100644 --- a/app/src/main/kotlin/viewmodel/screens/MainScreenViewModel.kt +++ b/app/src/main/kotlin/viewmodel/screens/MainScreenViewModel.kt @@ -111,8 +111,6 @@ class MainScreenViewModel( fun resetGraphView() { representationStrategy.place(800.0, 600.0, graphViewModel) - graphViewModel.vertices.forEach { v -> v.color = ColorTheme.vertexDefaultColor } - graphViewModel.edges.forEach { v -> v.color = ColorTheme.edgeDefaultColor } resetColors() } diff --git a/app/src/main/kotlin/viewmodel/screens/SqliteSaveViewModel.kt b/app/src/main/kotlin/viewmodel/screens/SqliteSaveViewModel.kt index db04a0b..89b76b3 100644 --- a/app/src/main/kotlin/viewmodel/screens/SqliteSaveViewModel.kt +++ b/app/src/main/kotlin/viewmodel/screens/SqliteSaveViewModel.kt @@ -14,7 +14,6 @@ class SqliteSaveViewModel( private var repo: SqliteRepository, private val graph: Graph, ) { - companion object { private val DB_EXTENSIONS = listOf(".db", ".sqlite", ".sqlite3", ".db3", ".s3db") } @@ -97,9 +96,10 @@ class SqliteSaveViewModel( val oldRepo = repo try { val dialog = FileDialog(null as Frame?, "Choose database file", FileDialog.LOAD) - dialog.filenameFilter = FilenameFilter { _, fname -> - DB_EXTENSIONS.any { ext -> fname.endsWith(ext) } - } + dialog.filenameFilter = + FilenameFilter { _, fname -> + DB_EXTENSIONS.any { ext -> fname.endsWith(ext) } + } dialog.isVisible = true dialog.file?.let { fileName -> val fullPath = File(dialog.directory, fileName).absolutePath @@ -123,4 +123,4 @@ class SqliteSaveViewModel( fun setMessage(message: String) { _message.value = message } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/viewmodel/screens/SqliteViewModel.kt b/app/src/main/kotlin/viewmodel/screens/SqliteViewModel.kt index f3f56b4..e082e08 100644 --- a/app/src/main/kotlin/viewmodel/screens/SqliteViewModel.kt +++ b/app/src/main/kotlin/viewmodel/screens/SqliteViewModel.kt @@ -10,8 +10,9 @@ import java.io.FilenameFilter import kotlin.io.path.Path import kotlin.io.path.exists -class SqliteViewModel(private var repo: SqliteRepository) { - +class SqliteViewModel( + private var repo: SqliteRepository, +) { companion object { private val DB_EXTENSIONS = listOf(".db", ".sqlite", ".sqlite3", ".db3", ".s3db") } @@ -33,7 +34,9 @@ class SqliteViewModel(private var repo: SqliteRepository) { private val _deleteDialog = mutableStateOf(false) val deleteDialog: State get() = _deleteDialog - init { reload() } + init { + reload() + } fun onFilterChange(searchQuery: String) { filter = searchQuery @@ -55,14 +58,18 @@ class SqliteViewModel(private var repo: SqliteRepository) { _message.value = message } - fun startDelete(id: Int, name: String) { + fun startDelete( + id: Int, + name: String, + ) { _toDelete.value = id to name _deleteDialog.value = true } fun confirmDelete() { _toDelete.value?.let { (id, _) -> repo.delete(id) } - reload(); cancelDelete() + reload() + cancelDelete() } fun cancelDelete() { @@ -74,9 +81,10 @@ class SqliteViewModel(private var repo: SqliteRepository) { val oldRepo = repo try { val dialog = FileDialog(null as Frame?, "Choose database file", FileDialog.LOAD) - dialog.filenameFilter = FilenameFilter { _, name -> - DB_EXTENSIONS.any { ext -> name.endsWith(ext) } - } + dialog.filenameFilter = + FilenameFilter { _, name -> + DB_EXTENSIONS.any { ext -> name.endsWith(ext) } + } dialog.isVisible = true dialog.file?.let { fileName -> diff --git a/app/src/test/kotlin/algorithms/FindBridgesTest.kt b/app/src/test/kotlin/algorithms/FindBridgesTest.kt index 1755bba..32dcd9d 100644 --- a/app/src/test/kotlin/algorithms/FindBridgesTest.kt +++ b/app/src/test/kotlin/algorithms/FindBridgesTest.kt @@ -1,13 +1,12 @@ package algorithms -import model.algo.findBridges.findBridges +import model.algo.findBridges import model.graph.Edge import model.graph.Graph import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test class FindBridgesTest { - /** * Graph without bridges */ diff --git a/app/src/test/kotlin/algorithms/FordBellmanTest.kt b/app/src/test/kotlin/algorithms/FordBellmanTest.kt index 2a09dbc..9701d02 100644 --- a/app/src/test/kotlin/algorithms/FordBellmanTest.kt +++ b/app/src/test/kotlin/algorithms/FordBellmanTest.kt @@ -1,6 +1,6 @@ package algorithms -import model.algo.fordBellman.fordBellman +import model.algo.fordBellman import model.graph.Graph import model.graph.Vertex import org.junit.jupiter.api.Assertions.assertEquals diff --git a/app/src/test/kotlin/integration/FordBellmanAndBridgeFindIntedrationTest.kt b/app/src/test/kotlin/integration/FordBellmanAndBridgeFindIntedrationTest.kt index 800bd3c..bed45fd 100644 --- a/app/src/test/kotlin/integration/FordBellmanAndBridgeFindIntedrationTest.kt +++ b/app/src/test/kotlin/integration/FordBellmanAndBridgeFindIntedrationTest.kt @@ -10,7 +10,6 @@ import viewmodel.colors.ColorTheme import viewmodel.graph.GraphViewModel class FordBellmanAndBridgeFindIntedrationTest { - /** * Test checks coloring vertexes and edges after algorithms using * diff --git a/app/src/test/kotlin/io/Neo4jTest.kt b/app/src/test/kotlin/io/Neo4jTest.kt index 0875a4d..a40c930 100644 --- a/app/src/test/kotlin/io/Neo4jTest.kt +++ b/app/src/test/kotlin/io/Neo4jTest.kt @@ -16,7 +16,6 @@ import org.neo4j.harness.Neo4jBuilders const val vertexCount = 100 const val edgesCount = 5 - /** * Testing input/output with neo4j graph database * For testing use library - neo4j harness (in-memory)