From 3de2f872bbae8295533f2a293c54374e2c4a3f30 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Wed, 10 Jul 2019 22:08:18 +0100 Subject: [PATCH] show results per sender --- .../com/muwire/gui/SearchTabController.groovy | 2 +- .../com/muwire/gui/SearchTabModel.groovy | 29 +++++-- .../views/com/muwire/gui/SearchTabView.groovy | 84 +++++++++++++++---- 3 files changed, 91 insertions(+), 24 deletions(-) diff --git a/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy b/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy index c46694d7..5fed879d 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy @@ -24,7 +24,7 @@ class SearchTabController { private def selectedResult() { int row = view.resultsTable.getSelectedRow() if (row == -1) - return + return null def sortEvt = view.lastSortEvent if (sortEvt != null) { row = view.resultsTable.rowSorter.convertRowIndexToModel(row) diff --git a/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy b/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy index e9cf0054..988fbb55 100644 --- a/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy @@ -5,6 +5,7 @@ import javax.inject.Inject import javax.swing.JTable import com.muwire.core.Core +import com.muwire.core.Persona import com.muwire.core.search.UIResultEvent import griffon.core.artifact.GriffonModel @@ -24,10 +25,12 @@ class SearchTabModel { Core core UISettings uiSettings String uuid + def senders = [] def results = [] def hashBucket = [:] def sourcesBucket = [:] - + def sendersBucket = new LinkedHashMap<>() + void mvcGroupInit(Map args) { core = mvcGroup.parentGroup.model.core @@ -51,6 +54,15 @@ class SearchTabModel { } bucket << e + def senderBucket = sendersBucket.get(e.sender) + if (senderBucket == null) { + senderBucket = [] + sendersBucket[e.sender] = senderBucket + senders.clear() + senders.addAll(sendersBucket.keySet()) + } + senderBucket << e + Set sourceBucket = sourcesBucket.get(e.infohash) if (sourceBucket == null) { sourceBucket = new HashSet() @@ -58,8 +70,7 @@ class SearchTabModel { } sourceBucket.addAll(e.sources) - results << e - JTable table = builder.getVariable("results-table") + JTable table = builder.getVariable("senders-table") table.model.fireTableDataChanged() } } @@ -75,6 +86,14 @@ class SearchTabModel { bucket = [] hashBucket[it.infohash] = bucket } + + def senderBucket = sendersBucket.get(it.sender) + if (senderBucket == null) { + senderBucket = [] + sendersBucket[it.sender] = senderBucket + senders.clear() + senders.addAll(sendersBucket.keySet()) + } Set sourceBucket = sourcesBucket.get(it.infohash) if (sourceBucket == null) { @@ -84,9 +103,9 @@ class SearchTabModel { sourceBucket.addAll(it.sources) bucket << it - results << it + senderBucket << it } - JTable table = builder.getVariable("results-table") + JTable table = builder.getVariable("senders-table") table.model.fireTableDataChanged() } } diff --git a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy index def2f8dd..4ac99f46 100644 --- a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy @@ -16,6 +16,7 @@ import javax.swing.ListSelectionModel import javax.swing.SwingConstants import javax.swing.table.DefaultTableCellRenderer +import com.muwire.core.Persona import com.muwire.core.util.DataUtil import java.awt.BorderLayout @@ -37,32 +38,50 @@ class SearchTabView { def pane def parent def searchTerms + def sendersTable + def lastSendersSortEvent def resultsTable def lastSortEvent void initUI() { builder.with { def resultsTable + def sendersTable def pane = panel { - borderLayout() - scrollPane (constraints : BorderLayout.CENTER) { - resultsTable = table(id : "results-table", autoCreateRowSorter : true) { - tableModel(list: model.results) { - closureColumn(header: "Name", preferredWidth: 350, type: String, read : {row -> row.name.replace('<','_')}) - closureColumn(header: "Size", preferredWidth: 20, type: Long, read : {row -> row.size}) - closureColumn(header: "Direct Sources", preferredWidth: 50, type : Integer, read : { row -> model.hashBucket[row.infohash].size()}) - closureColumn(header: "Possible Sources", preferredWidth : 50, type : Integer, read : {row -> model.sourcesBucket[row.infohash].size()}) - closureColumn(header: "Sender", preferredWidth: 170, type: String, read : {row -> row.sender.getHumanReadableName()}) - closureColumn(header: "Trust", preferredWidth: 50, type: String, read : {row -> - model.core.trustService.getLevel(row.sender.destination).toString() - }) + gridLayout(rows : 2, cols: 1) + panel { + borderLayout() + scrollPane (constraints : BorderLayout.CENTER) { + sendersTable = table(id : "senders-table", autoCreateRowSorter : true) { + tableModel(list : model.senders) { + closureColumn(header : "Sender", type: String, read : {row -> row.getHumanReadableName()}) + closureColumn(header : "Results", type: Integer, read : {row -> model.sendersBucket[row].size()}) + closureColumn(header : "Trust", type: String, read : { row -> + model.core.trustService.getLevel(row.destination).toString() + }) + } } } + panel(constraints : BorderLayout.SOUTH) { + button(text : "Trust", enabled: bind {model.trustButtonsEnabled }, trustAction) + button(text : "Distrust", enabled : bind {model.trustButtonsEnabled}, distrustAction) + } } - panel(constraints : BorderLayout.SOUTH) { - button(text : "Download", enabled : bind {model.downloadActionEnabled}, downloadAction) - button(text : "Trust", enabled: bind {model.trustButtonsEnabled }, trustAction) - button(text : "Distrust", enabled : bind {model.trustButtonsEnabled}, distrustAction) + panel { + borderLayout() + scrollPane (constraints : BorderLayout.CENTER) { + resultsTable = table(id : "results-table", autoCreateRowSorter : true) { + tableModel(list: model.results) { + closureColumn(header: "Name", preferredWidth: 350, type: String, read : {row -> row.name.replace('<','_')}) + closureColumn(header: "Size", preferredWidth: 20, type: Long, read : {row -> row.size}) + closureColumn(header: "Direct Sources", preferredWidth: 50, type : Integer, read : { row -> model.hashBucket[row.infohash].size()}) + closureColumn(header: "Possible Sources", preferredWidth : 50, type : Integer, read : {row -> model.sourcesBucket[row.infohash].size()}) + } + } + } + panel(constraints : BorderLayout.SOUTH) { + button(text : "Download", enabled : bind {model.downloadActionEnabled}, downloadAction) + } } } @@ -71,6 +90,7 @@ class SearchTabView { this.pane.putClientProperty("results-table",resultsTable) this.resultsTable = resultsTable + this.sendersTable = sendersTable def selectionModel = resultsTable.getSelectionModel() selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) @@ -109,9 +129,7 @@ class SearchTabView { def centerRenderer = new DefaultTableCellRenderer() centerRenderer.setHorizontalAlignment(JLabel.CENTER) - resultsTable.columnModel.getColumn(1).setCellRenderer(centerRenderer) resultsTable.setDefaultRenderer(Integer.class,centerRenderer) - resultsTable.columnModel.getColumn(4).setCellRenderer(centerRenderer) resultsTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer()) @@ -134,6 +152,27 @@ class SearchTabView { showPopupMenu(e) } }) + + // senders table + sendersTable.setDefaultRenderer(Integer.class, centerRenderer) + sendersTable.rowSorter.addRowSorterListener({evt -> lastSendersSortEvent = evt}) + sendersTable.rowSorter.setSortsOnUpdates(true) + def selectionModel = sendersTable.getSelectionModel() + selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) + selectionModel.addListSelectionListener({ + int row = selectedSenderRow() + if (row < 0) { + model.trustButtonsEnabled = false + return + } else { + model.trustButtonsEnabled = true + model.results.clear() + Persona p = model.senders[row] + model.results.addAll(model.sendersBucket[p]) + resultsTable.model.fireTableDataChanged() + } + }) + } def closeTab = { @@ -168,4 +207,13 @@ class SearchTabView { def clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() clipboard.setContents(selection, null) } + + int selectedSenderRow() { + int row = sendersTable.getSelectedRow() + if (row < 0) + return -1 + if (lastSendersSortEvent != null) + row = sendersTable.rowSorter.convertRowIndexToModel(row) + row + } } \ No newline at end of file