Compare commits

...

9 Commits

Author SHA1 Message Date
Zlatin Balevsky
5a54b2dcda shift focus to search pane on search 2019-07-10 22:33:21 +01:00
Zlatin Balevsky
581293b24f column sizes 2019-07-10 22:27:07 +01:00
Zlatin Balevsky
cd072b9f76 enable/disable download button correctly 2019-07-10 22:23:20 +01:00
Zlatin Balevsky
6b74fc5956 fix trust/distrust buttons 2019-07-10 22:17:32 +01:00
Zlatin Balevsky
3de2f872bb show results per sender 2019-07-10 22:08:18 +01:00
Zlatin Balevsky
fcde917d08 fix context menu and double-click 2019-07-10 21:26:13 +01:00
Zlatin Balevsky
4ded065010 move buttons onto search result tab 2019-07-10 21:23:00 +01:00
Zlatin Balevsky
18a1c7091a move downloads to their own pane 2019-07-10 20:54:45 +01:00
Zlatin Balevsky
46aee19f80 disable the button of the currently open pane 2019-07-10 20:37:09 +01:00
6 changed files with 244 additions and 111 deletions

View File

@@ -59,6 +59,7 @@ class MainFrameController {
Map<String, Object> params = new HashMap<>() Map<String, Object> params = new HashMap<>()
params["search-terms"] = search params["search-terms"] = search
params["uuid"] = uuid.toString() params["uuid"] = uuid.toString()
params["core"] = core
def group = mvcGroup.createMVCGroup("SearchTab", uuid.toString(), params) def group = mvcGroup.createMVCGroup("SearchTab", uuid.toString(), params)
model.results[uuid.toString()] = group model.results[uuid.toString()] = group
@@ -96,6 +97,7 @@ class MainFrameController {
Map<String, Object> params = new HashMap<>() Map<String, Object> params = new HashMap<>()
params["search-terms"] = tabTitle params["search-terms"] = tabTitle
params["uuid"] = uuid.toString() params["uuid"] = uuid.toString()
params["core"] = core
def group = mvcGroup.createMVCGroup("SearchTab", uuid.toString(), params) def group = mvcGroup.createMVCGroup("SearchTab", uuid.toString(), params)
model.results[uuid.toString()] = group model.results[uuid.toString()] = group
@@ -106,20 +108,6 @@ class MainFrameController {
originator : core.me)) originator : core.me))
} }
private def selectedResult() {
def selected = builder.getVariable("result-tabs").getSelectedComponent()
def group = selected.getClientProperty("mvc-group")
def table = selected.getClientProperty("results-table")
int row = table.getSelectedRow()
if (row == -1)
return
def sortEvt = group.view.lastSortEvent
if (sortEvt != null) {
row = group.view.resultsTable.rowSorter.convertRowIndexToModel(row)
}
group.model.results[row]
}
private int selectedDownload() { private int selectedDownload() {
def downloadsTable = builder.getVariable("downloads-table") def downloadsTable = builder.getVariable("downloads-table")
def selected = downloadsTable.getSelectedRow() def selected = downloadsTable.getSelectedRow()
@@ -129,42 +117,6 @@ class MainFrameController {
selected selected
} }
@ControllerAction
void download() {
def result = selectedResult()
if (result == null)
return
if (!model.canDownload(result.infohash))
return
def file = new File(application.context.get("muwire-settings").downloadLocation, result.name)
def selected = builder.getVariable("result-tabs").getSelectedComponent()
def group = selected.getClientProperty("mvc-group")
def resultsBucket = group.model.hashBucket[result.infohash]
def sources = group.model.sourcesBucket[result.infohash]
core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources, target : file))
}
@ControllerAction
void trust() {
def result = selectedResult()
if (result == null)
return // TODO disable button
core.eventBus.publish( new TrustEvent(persona : result.sender, level : TrustLevel.TRUSTED))
}
@ControllerAction
void distrust() {
def result = selectedResult()
if (result == null)
return // TODO disable button
core.eventBus.publish( new TrustEvent(persona : result.sender, level : TrustLevel.DISTRUSTED))
}
@ControllerAction @ControllerAction
void trustPersonaFromSearch() { void trustPersonaFromSearch() {
int selected = builder.getVariable("searches-table").getSelectedRow() int selected = builder.getVariable("searches-table").getSelectedRow()

View File

@@ -6,6 +6,65 @@ import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor import griffon.metadata.ArtifactProviderFor
import javax.annotation.Nonnull import javax.annotation.Nonnull
import com.muwire.core.Core
import com.muwire.core.download.UIDownloadEvent
import com.muwire.core.trust.TrustEvent
import com.muwire.core.trust.TrustLevel
@ArtifactProviderFor(GriffonController) @ArtifactProviderFor(GriffonController)
class SearchTabController { class SearchTabController {
@MVCMember @Nonnull
SearchTabModel model
@MVCMember @Nonnull
SearchTabView view
Core core
private def selectedResult() {
int row = view.resultsTable.getSelectedRow()
if (row == -1)
return null
def sortEvt = view.lastSortEvent
if (sortEvt != null) {
row = view.resultsTable.rowSorter.convertRowIndexToModel(row)
}
model.results[row]
}
@ControllerAction
void download() {
def result = selectedResult()
if (result == null)
return
if (!mvcGroup.parentGroup.model.canDownload(result.infohash))
return
def file = new File(application.context.get("muwire-settings").downloadLocation, result.name)
def resultsBucket = model.hashBucket[result.infohash]
def sources = model.sourcesBucket[result.infohash]
core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources, target : file))
mvcGroup.parentGroup.view.showDownloadsWindow.call()
}
@ControllerAction
void trust() {
int row = view.selectedSenderRow()
if (row < 0)
return
def sender = model.senders[row]
core.eventBus.publish( new TrustEvent(persona : sender, level : TrustLevel.TRUSTED))
}
@ControllerAction
void distrust() {
int row = view.selectedSenderRow()
if (row < 0)
return
def sender = model.senders[row]
core.eventBus.publish( new TrustEvent(persona : sender, level : TrustLevel.DISTRUSTED))
}
} }

View File

@@ -76,8 +76,6 @@ class MainFrameModel {
@Observable String me @Observable String me
@Observable int loadedFiles @Observable int loadedFiles
@Observable File hashingFile @Observable File hashingFile
@Observable boolean downloadActionEnabled
@Observable boolean trustButtonsEnabled
@Observable boolean cancelButtonEnabled @Observable boolean cancelButtonEnabled
@Observable boolean retryButtonEnabled @Observable boolean retryButtonEnabled
@Observable boolean pauseButtonEnabled @Observable boolean pauseButtonEnabled
@@ -90,6 +88,12 @@ class MainFrameModel {
@Observable boolean reviewButtonEnabled @Observable boolean reviewButtonEnabled
@Observable boolean updateButtonEnabled @Observable boolean updateButtonEnabled
@Observable boolean unsubscribeButtonEnabled @Observable boolean unsubscribeButtonEnabled
@Observable boolean searchesPaneButtonEnabled
@Observable boolean downloadsPaneButtonEnabled
@Observable boolean uploadsPaneButtonEnabled
@Observable boolean monitorPaneButtonEnabled
@Observable boolean trustPaneButtonEnabled
private final Set<InfoHash> infoHashes = new HashSet<>() private final Set<InfoHash> infoHashes = new HashSet<>()
@@ -200,6 +204,12 @@ class MainFrameModel {
distrusted.addAll(core.trustService.bad.values()) distrusted.addAll(core.trustService.bad.values())
resumeButtonText = "Retry" resumeButtonText = "Retry"
searchesPaneButtonEnabled = false
downloadsPaneButtonEnabled = true
uploadsPaneButtonEnabled = true
monitorPaneButtonEnabled = true
trustPaneButtonEnabled = true
} }
}) })

View File

@@ -5,6 +5,7 @@ import javax.inject.Inject
import javax.swing.JTable import javax.swing.JTable
import com.muwire.core.Core import com.muwire.core.Core
import com.muwire.core.Persona
import com.muwire.core.search.UIResultEvent import com.muwire.core.search.UIResultEvent
import griffon.core.artifact.GriffonModel import griffon.core.artifact.GriffonModel
@@ -17,14 +18,19 @@ import griffon.metadata.ArtifactProviderFor
class SearchTabModel { class SearchTabModel {
@MVCMember @Nonnull @MVCMember @Nonnull
FactoryBuilderSupport builder FactoryBuilderSupport builder
@Observable boolean downloadActionEnabled
@Observable boolean trustButtonsEnabled
Core core Core core
UISettings uiSettings UISettings uiSettings
String uuid String uuid
def senders = []
def results = [] def results = []
def hashBucket = [:] def hashBucket = [:]
def sourcesBucket = [:] def sourcesBucket = [:]
def sendersBucket = new LinkedHashMap<>()
void mvcGroupInit(Map<String, String> args) { void mvcGroupInit(Map<String, String> args) {
core = mvcGroup.parentGroup.model.core core = mvcGroup.parentGroup.model.core
@@ -48,6 +54,15 @@ class SearchTabModel {
} }
bucket << e 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) Set sourceBucket = sourcesBucket.get(e.infohash)
if (sourceBucket == null) { if (sourceBucket == null) {
sourceBucket = new HashSet() sourceBucket = new HashSet()
@@ -55,8 +70,7 @@ class SearchTabModel {
} }
sourceBucket.addAll(e.sources) sourceBucket.addAll(e.sources)
results << e JTable table = builder.getVariable("senders-table")
JTable table = builder.getVariable("results-table")
table.model.fireTableDataChanged() table.model.fireTableDataChanged()
} }
} }
@@ -72,6 +86,14 @@ class SearchTabModel {
bucket = [] bucket = []
hashBucket[it.infohash] = 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) Set sourceBucket = sourcesBucket.get(it.infohash)
if (sourceBucket == null) { if (sourceBucket == null) {
@@ -81,9 +103,9 @@ class SearchTabModel {
sourceBucket.addAll(it.sources) sourceBucket.addAll(it.sources)
bucket << it bucket << it
results << it senderBucket << it
} }
JTable table = builder.getVariable("results-table") JTable table = builder.getVariable("senders-table")
table.model.fireTableDataChanged() table.model.fireTableDataChanged()
} }
} }

View File

@@ -89,11 +89,12 @@ class MainFrameView {
borderLayout() borderLayout()
panel (constraints: BorderLayout.WEST) { panel (constraints: BorderLayout.WEST) {
gridLayout(rows:1, cols: 2) gridLayout(rows:1, cols: 2)
button(text: "Searches", actionPerformed : showSearchWindow) button(text: "Searches", enabled : bind{model.searchesPaneButtonEnabled},actionPerformed : showSearchWindow)
button(text: "Uploads", actionPerformed : showUploadsWindow) button(text: "Downloads", enabled : bind{model.downloadsPaneButtonEnabled}, actionPerformed : showDownloadsWindow)
button(text: "Uploads", enabled : bind{model.uploadsPaneButtonEnabled}, actionPerformed : showUploadsWindow)
if (settings.showMonitor) if (settings.showMonitor)
button(text: "Monitor", actionPerformed : showMonitorWindow) button(text: "Monitor", enabled: bind{model.monitorPaneButtonEnabled},actionPerformed : showMonitorWindow)
button(text: "Trust", actionPerformed : showTrustWindow) button(text: "Trust", enabled:bind{model.trustPaneButtonEnabled},actionPerformed : showTrustWindow)
} }
panel(id: "top-panel", constraints: BorderLayout.CENTER) { panel(id: "top-panel", constraints: BorderLayout.CENTER) {
cardLayout() cardLayout()
@@ -117,37 +118,38 @@ class MainFrameView {
cardLayout() cardLayout()
panel (constraints : "search window") { panel (constraints : "search window") {
borderLayout() borderLayout()
splitPane( orientation : JSplitPane.VERTICAL_SPLIT, dividerLocation : 500, tabbedPane(id : "result-tabs", constraints: BorderLayout.CENTER)
continuousLayout : true, constraints : BorderLayout.CENTER) { }
panel (constraints : JSplitPane.TOP) { panel (constraints: "downloads window") {
borderLayout() gridLayout(rows : 2, cols: 1)
tabbedPane(id : "result-tabs", constraints: BorderLayout.CENTER) panel {
panel(constraints : BorderLayout.SOUTH) { borderLayout()
button(text : "Download", enabled : bind {model.downloadActionEnabled}, downloadAction) scrollPane (constraints : BorderLayout.CENTER) {
button(text : "Trust", enabled: bind {model.trustButtonsEnabled }, trustAction) downloadsTable = table(id : "downloads-table", autoCreateRowSorter : true) {
button(text : "Distrust", enabled : bind {model.trustButtonsEnabled}, distrustAction) tableModel(list: model.downloads) {
} closureColumn(header: "Name", preferredWidth: 300, type: String, read : {row -> row.downloader.file.getName()})
} closureColumn(header: "Status", preferredWidth: 50, type: String, read : {row -> row.downloader.getCurrentState().toString()})
panel (constraints : JSplitPane.BOTTOM) { closureColumn(header: "Progress", preferredWidth: 70, type: Downloader, read: { row -> row.downloader })
borderLayout() closureColumn(header: "Sources", preferredWidth : 10, type: Integer, read : {row -> row.downloader.activeWorkers()})
scrollPane (constraints : BorderLayout.CENTER) { closureColumn(header: "Speed", preferredWidth: 50, type:String, read :{row ->
downloadsTable = table(id : "downloads-table", autoCreateRowSorter : true) { DataHelper.formatSize2Decimal(row.downloader.speed(), false) + "B/sec"
tableModel(list: model.downloads) { })
closureColumn(header: "Name", preferredWidth: 300, type: String, read : {row -> row.downloader.file.getName()})
closureColumn(header: "Status", preferredWidth: 50, type: String, read : {row -> row.downloader.getCurrentState().toString()})
closureColumn(header: "Progress", preferredWidth: 70, type: Downloader, read: { row -> row.downloader })
closureColumn(header: "Sources", preferredWidth : 10, type: Integer, read : {row -> row.downloader.activeWorkers()})
closureColumn(header: "Speed", preferredWidth: 50, type:String, read :{row ->
DataHelper.formatSize2Decimal(row.downloader.speed(), false) + "B/sec"
})
}
} }
} }
panel (constraints : BorderLayout.SOUTH) { }
button(text: "Pause", enabled : bind {model.pauseButtonEnabled}, pauseAction) panel (constraints : BorderLayout.SOUTH) {
button(text: "Cancel", enabled : bind {model.cancelButtonEnabled }, cancelAction ) button(text: "Pause", enabled : bind {model.pauseButtonEnabled}, pauseAction)
button(text: bind { model.resumeButtonText }, enabled : bind {model.retryButtonEnabled}, resumeAction) button(text: "Cancel", enabled : bind {model.cancelButtonEnabled }, cancelAction )
} button(text: bind { model.resumeButtonText }, enabled : bind {model.retryButtonEnabled}, resumeAction)
}
}
panel {
borderLayout()
panel(constraints : BorderLayout.NORTH) {
label(text : "Download Details")
}
panel(constraints : BorderLayout.CENTER) {
label(text : "Details go here...")
} }
} }
} }
@@ -690,21 +692,51 @@ class MainFrameView {
def showSearchWindow = { def showSearchWindow = {
def cardsPanel = builder.getVariable("cards-panel") def cardsPanel = builder.getVariable("cards-panel")
cardsPanel.getLayout().show(cardsPanel, "search window") cardsPanel.getLayout().show(cardsPanel, "search window")
model.searchesPaneButtonEnabled = false
model.downloadsPaneButtonEnabled = true
model.uploadsPaneButtonEnabled = true
model.monitorPaneButtonEnabled = true
model.trustPaneButtonEnabled = true
}
def showDownloadsWindow = {
def cardsPanel = builder.getVariable("cards-panel")
cardsPanel.getLayout().show(cardsPanel, "downloads window")
model.searchesPaneButtonEnabled = true
model.downloadsPaneButtonEnabled = false
model.uploadsPaneButtonEnabled = true
model.monitorPaneButtonEnabled = true
model.trustPaneButtonEnabled = true
} }
def showUploadsWindow = { def showUploadsWindow = {
def cardsPanel = builder.getVariable("cards-panel") def cardsPanel = builder.getVariable("cards-panel")
cardsPanel.getLayout().show(cardsPanel, "uploads window") cardsPanel.getLayout().show(cardsPanel, "uploads window")
model.searchesPaneButtonEnabled = true
model.downloadsPaneButtonEnabled = true
model.uploadsPaneButtonEnabled = false
model.monitorPaneButtonEnabled = true
model.trustPaneButtonEnabled = true
} }
def showMonitorWindow = { def showMonitorWindow = {
def cardsPanel = builder.getVariable("cards-panel") def cardsPanel = builder.getVariable("cards-panel")
cardsPanel.getLayout().show(cardsPanel,"monitor window") cardsPanel.getLayout().show(cardsPanel,"monitor window")
model.searchesPaneButtonEnabled = true
model.downloadsPaneButtonEnabled = true
model.uploadsPaneButtonEnabled = true
model.monitorPaneButtonEnabled = false
model.trustPaneButtonEnabled = true
} }
def showTrustWindow = { def showTrustWindow = {
def cardsPanel = builder.getVariable("cards-panel") def cardsPanel = builder.getVariable("cards-panel")
cardsPanel.getLayout().show(cardsPanel,"trust window") cardsPanel.getLayout().show(cardsPanel,"trust window")
model.searchesPaneButtonEnabled = true
model.downloadsPaneButtonEnabled = true
model.uploadsPaneButtonEnabled = true
model.monitorPaneButtonEnabled = true
model.trustPaneButtonEnabled = false
} }
def shareFiles = { def shareFiles = {

View File

@@ -16,6 +16,7 @@ import javax.swing.ListSelectionModel
import javax.swing.SwingConstants import javax.swing.SwingConstants
import javax.swing.table.DefaultTableCellRenderer import javax.swing.table.DefaultTableCellRenderer
import com.muwire.core.Persona
import com.muwire.core.util.DataUtil import com.muwire.core.util.DataUtil
import java.awt.BorderLayout import java.awt.BorderLayout
@@ -37,23 +38,49 @@ class SearchTabView {
def pane def pane
def parent def parent
def searchTerms def searchTerms
def sendersTable
def lastSendersSortEvent
def resultsTable def resultsTable
def lastSortEvent def lastSortEvent
void initUI() { void initUI() {
builder.with { builder.with {
def resultsTable def resultsTable
def pane = scrollPane { def sendersTable
resultsTable = table(id : "results-table", autoCreateRowSorter : true) { def pane = panel {
tableModel(list: model.results) { gridLayout(rows : 2, cols: 1)
closureColumn(header: "Name", preferredWidth: 350, type: String, read : {row -> row.name.replace('<','_')}) panel {
closureColumn(header: "Size", preferredWidth: 20, type: Long, read : {row -> row.size}) borderLayout()
closureColumn(header: "Direct Sources", preferredWidth: 50, type : Integer, read : { row -> model.hashBucket[row.infohash].size()}) scrollPane (constraints : BorderLayout.CENTER) {
closureColumn(header: "Possible Sources", preferredWidth : 50, type : Integer, read : {row -> model.sourcesBucket[row.infohash].size()}) sendersTable = table(id : "senders-table", autoCreateRowSorter : true) {
closureColumn(header: "Sender", preferredWidth: 170, type: String, read : {row -> row.sender.getHumanReadableName()}) tableModel(list : model.senders) {
closureColumn(header: "Trust", preferredWidth: 50, type: String, read : {row -> closureColumn(header : "Sender", preferredWidth : 500, type: String, read : {row -> row.getHumanReadableName()})
model.core.trustService.getLevel(row.sender.destination).toString() closureColumn(header : "Results", preferredWidth : 20, type: Integer, read : {row -> model.sendersBucket[row].size()})
}) closureColumn(header : "Trust", preferredWidth : 50, 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 {
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)
} }
} }
} }
@@ -63,17 +90,19 @@ class SearchTabView {
this.pane.putClientProperty("results-table",resultsTable) this.pane.putClientProperty("results-table",resultsTable)
this.resultsTable = resultsTable this.resultsTable = resultsTable
this.sendersTable = sendersTable
def selectionModel = resultsTable.getSelectionModel() def selectionModel = resultsTable.getSelectionModel()
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
selectionModel.addListSelectionListener( { selectionModel.addListSelectionListener( {
int row = resultsTable.getSelectedRow() int row = resultsTable.getSelectedRow()
if (row < 0) if (row < 0) {
model.downloadActionEnabled = false
return return
}
if (lastSortEvent != null) if (lastSortEvent != null)
row = resultsTable.rowSorter.convertRowIndexToModel(row) row = resultsTable.rowSorter.convertRowIndexToModel(row)
mvcGroup.parentGroup.model.trustButtonsEnabled = true model.downloadActionEnabled = mvcGroup.parentGroup.model.canDownload(model.results[row].infohash)
mvcGroup.parentGroup.model.downloadActionEnabled = mvcGroup.parentGroup.model.canDownload(model.results[row].infohash)
}) })
} }
} }
@@ -98,12 +127,11 @@ class SearchTabView {
} }
parent.setTabComponentAt(index, tabPanel) parent.setTabComponentAt(index, tabPanel)
mvcGroup.parentGroup.view.showSearchWindow.call()
def centerRenderer = new DefaultTableCellRenderer() def centerRenderer = new DefaultTableCellRenderer()
centerRenderer.setHorizontalAlignment(JLabel.CENTER) centerRenderer.setHorizontalAlignment(JLabel.CENTER)
resultsTable.columnModel.getColumn(1).setCellRenderer(centerRenderer)
resultsTable.setDefaultRenderer(Integer.class,centerRenderer) resultsTable.setDefaultRenderer(Integer.class,centerRenderer)
resultsTable.columnModel.getColumn(4).setCellRenderer(centerRenderer)
resultsTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer()) resultsTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer())
@@ -118,7 +146,7 @@ class SearchTabView {
if (e.button == MouseEvent.BUTTON3) if (e.button == MouseEvent.BUTTON3)
showPopupMenu(e) showPopupMenu(e)
else if (e.button == MouseEvent.BUTTON1 && e.clickCount == 2) else if (e.button == MouseEvent.BUTTON1 && e.clickCount == 2)
mvcGroup.parentGroup.controller.download() mvcGroup.controller.download()
} }
@Override @Override
public void mouseReleased(MouseEvent e) { public void mouseReleased(MouseEvent e) {
@@ -126,21 +154,42 @@ class SearchTabView {
showPopupMenu(e) 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 = { def closeTab = {
int index = parent.indexOfTab(searchTerms) int index = parent.indexOfTab(searchTerms)
parent.removeTabAt(index) parent.removeTabAt(index)
mvcGroup.parentGroup.model.trustButtonsEnabled = false model.trustButtonsEnabled = false
mvcGroup.parentGroup.model.downloadActionEnabled = false model.downloadActionEnabled = false
mvcGroup.destroy() mvcGroup.destroy()
} }
def showPopupMenu(MouseEvent e) { def showPopupMenu(MouseEvent e) {
JPopupMenu menu = new JPopupMenu() JPopupMenu menu = new JPopupMenu()
if (mvcGroup.parentGroup.model.downloadActionEnabled) { if (model.downloadActionEnabled) {
JMenuItem download = new JMenuItem("Download") JMenuItem download = new JMenuItem("Download")
download.addActionListener({mvcGroup.parentGroup.controller.download()}) download.addActionListener({mvcGroup.controller.download()})
menu.add(download) menu.add(download)
} }
JMenuItem copyHashToClipboard = new JMenuItem("Copy hash to clipboard") JMenuItem copyHashToClipboard = new JMenuItem("Copy hash to clipboard")
@@ -160,4 +209,13 @@ class SearchTabView {
def clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() def clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
clipboard.setContents(selection, null) clipboard.setContents(selection, null)
} }
int selectedSenderRow() {
int row = sendersTable.getSelectedRow()
if (row < 0)
return -1
if (lastSendersSortEvent != null)
row = sendersTable.rowSorter.convertRowIndexToModel(row)
row
}
} }