From ee6cb895aa523df6878477d2b311e55a96b71c2d Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Tue, 11 Nov 2025 20:20:46 +0100 Subject: [PATCH] implement move up/down for feed groups --- .../kotlin/de/unixwork/rssreader/Database.kt | 20 +++++++++++++++ .../de/unixwork/rssreader/FeedSourceList.kt | 25 ++++++++++++++++++- .../de/unixwork/rssreader/MainWindow.kt | 18 ++++++++++--- .../main/java/de/unixwork/ui/ListFuncs.java | 4 +++ .../java/de/unixwork/ui/UiSourceList.java | 13 ++++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt index a1747e1..d264a02 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt @@ -184,6 +184,26 @@ object Database { } } + public fun swapFeedGroupPos(group1: FeedGroup, group2: FeedGroup) { + val sql = """ + update groups set + pos = case + when group_id = ?1 then (SELECT pos from groups where group_id = ?2) + when group_id = ?2 then (SELECT pos from groups where group_id = ?1) + else pos + end + where group_id in (?1, ?2) + """.trimIndent() + + dataSource.connection.use { conn -> + conn.prepareStatement(sql).use { stmt -> + stmt.setInt(1, group1.id) + stmt.setInt(2, group2.id) + stmt.execute() + } + } + } + public fun newFeedGroup(context: Context, name: String) : FeedGroup { var groupId = 0 dataSource.connection.use { conn -> diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt index ed18216..873bd50 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt @@ -50,7 +50,30 @@ class FeedSourceList : Document() { gr.feeds[feed2] = f1 gr.feeds.update() - Database.swapFeedCollectionPos(f1, f2) + GlobalScope.launch(Dispatchers.IO) { + Database.swapFeedCollectionPos(f1, f2) + } + } + + fun swapFeedGroups(group1: Int, group2: Int) { + if(group1 < 0 || group1 >= groups.size) { + return + } + if(group2 < 0 || group2 >= groups.size) { + return + } + + // swap groups in the list and in the database + feeds.swap(group1, group2) + val g1 = groups[group1] + val g2 = groups[group2] + groups[group1] = g2 + groups[group2] = g1 + feeds.update() + + GlobalScope.launch(Dispatchers.IO) { + Database.swapFeedGroupPos(g1, g2) + } } fun invalidateCache() { diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt index 5ea10e0..70131b6 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt @@ -77,16 +77,26 @@ class MainWindow() { separator() menuItem("Move Up") { event -> val evt = event.subListEventData - sourceList.swapFeedCollections(evt.sublistIndex, evt.rowIndex, evt.rowIndex-1) + if(evt.rowIndex >= 0) { + sourceList.swapFeedCollections(evt.sublistIndex, evt.rowIndex, evt.rowIndex-1) + } else { + sourceList.swapFeedGroups(evt.sublistIndex, evt.sublistIndex-1) + } } menuItem("Move Down") { event -> val evt = event.subListEventData - sourceList.swapFeedCollections(evt.sublistIndex, evt.rowIndex, evt.rowIndex+1) + if(evt.rowIndex >= 0) { + sourceList.swapFeedCollections(evt.sublistIndex, evt.rowIndex, evt.rowIndex+1) + } else { + sourceList.swapFeedGroups(evt.sublistIndex, evt.sublistIndex+1) + } } - menuItem("Delete") { + menuItem("Delete") { event -> + val evt = event.subListEventData + } separator() - menuItem("Settings") { + menuItem("Settings") { event -> } } diff --git a/ui-java/src/main/java/de/unixwork/ui/ListFuncs.java b/ui-java/src/main/java/de/unixwork/ui/ListFuncs.java index f0ae1df..515be3e 100644 --- a/ui-java/src/main/java/de/unixwork/ui/ListFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/ListFuncs.java @@ -30,6 +30,7 @@ public class ListFuncs { public MethodHandle srclist_add; public MethodHandle srclist_insert; public MethodHandle srclist_remove; + public MethodHandle srclist_swap; public MethodHandle srclist_clear; public MethodHandle srclist_size; public MethodHandle srclist_generate_sublist_num_data; @@ -47,6 +48,7 @@ public class ListFuncs { FunctionDescriptor sigv_mim = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS); FunctionDescriptor sigv_mmi = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); FunctionDescriptor sigv_mi = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT); + FunctionDescriptor sigv_mii = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT); FunctionDescriptor sigv_m = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS); FunctionDescriptor sigi_m = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); @@ -74,6 +76,7 @@ public class ListFuncs { MemorySegment ui_srclist_add_addr = lib.find("ui_srclist_add").orElseThrow(); MemorySegment ui_srclist_insert_addr = lib.find("ui_srclist_insert").orElseThrow(); MemorySegment ui_srclist_remove_addr = lib.find("ui_srclist_remove").orElseThrow(); + MemorySegment ui_srclist_swap_addr = lib.find("ui_srclist_swap").orElseThrow(); MemorySegment ui_srclist_clear_addr = lib.find("ui_srclist_clear").orElseThrow(); MemorySegment ui_srclist_size_addr = lib.find("ui_srclist_size").orElseThrow(); MemorySegment ui_srclist_generate_sublist_num_data_addr = lib.find("ui_srclist_generate_sublist_num_data").orElseThrow(); @@ -107,6 +110,7 @@ public class ListFuncs { srclist_add = linker.downcallHandle(ui_srclist_add_addr, sigv_mm); srclist_insert = linker.downcallHandle(ui_srclist_insert_addr, sigv_mim); srclist_remove = linker.downcallHandle(ui_srclist_remove_addr, sigv_mi); + srclist_swap = linker.downcallHandle(ui_srclist_swap_addr, sigv_mii); srclist_clear = linker.downcallHandle(ui_srclist_remove_addr, sigv_m); srclist_size = linker.downcallHandle(ui_srclist_size_addr, sigi_m); srclist_generate_sublist_num_data = linker.downcallHandle(ui_srclist_generate_sublist_num_data_addr, sigv_m); diff --git a/ui-java/src/main/java/de/unixwork/ui/UiSourceList.java b/ui-java/src/main/java/de/unixwork/ui/UiSourceList.java index 9f02868..f644889 100644 --- a/ui-java/src/main/java/de/unixwork/ui/UiSourceList.java +++ b/ui-java/src/main/java/de/unixwork/ui/UiSourceList.java @@ -56,6 +56,19 @@ public class UiSourceList { return list.get(index); } + public void swap(int index1, int index2) { + var e1 = list.get(index1); + var e2 = list.get(index2); + list.set(index1, e2); + list.set(index2, e1); + ListFuncs ui = ListFuncs.getInstance(); + try { + ui.srclist_swap.invoke(valuePtr, index1, index2); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + public void update() { ListFuncs ui = ListFuncs.getInstance(); try { -- 2.47.3