mirror of https://github.com/zlatinb/muwire
add filtering in browse host view
parent
0b2fd2017a
commit
a0ce1655ce
|
@ -1,5 +1,6 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import com.muwire.core.SplitPattern
|
||||
import griffon.core.artifact.GriffonController
|
||||
import griffon.core.controller.ControllerAction
|
||||
import griffon.inject.MVCMember
|
||||
|
@ -9,7 +10,6 @@ import net.i2p.data.Base64
|
|||
import javax.annotation.Nonnull
|
||||
|
||||
import com.muwire.core.Core
|
||||
import com.muwire.core.EventBus
|
||||
import com.muwire.core.download.UIDownloadEvent
|
||||
import com.muwire.core.search.BrowseStatus
|
||||
import com.muwire.core.search.BrowseStatusEvent
|
||||
|
@ -17,8 +17,12 @@ import com.muwire.core.search.UIBrowseEvent
|
|||
import com.muwire.core.search.UIResultBatchEvent
|
||||
import com.muwire.core.search.UIResultEvent
|
||||
|
||||
import javax.swing.JTextField
|
||||
|
||||
@ArtifactProviderFor(GriffonController)
|
||||
class BrowseController {
|
||||
@MVCMember @Nonnull
|
||||
FactoryBuilderSupport builder
|
||||
@MVCMember @Nonnull
|
||||
BrowseModel model
|
||||
@MVCMember @Nonnull
|
||||
|
@ -44,6 +48,8 @@ class BrowseController {
|
|||
return
|
||||
runInsideUIAsync {
|
||||
model.status = e.status
|
||||
model.filterEnabled = (e.status == BrowseStatus.FINISHED || e.status == BrowseStatus.FAILED) &&
|
||||
model.resultCount > 0
|
||||
if (e.status == BrowseStatus.FETCHING)
|
||||
model.totalResults = e.totalResults
|
||||
}
|
||||
|
@ -54,23 +60,35 @@ class BrowseController {
|
|||
if (e.uuid != model.uuid)
|
||||
return
|
||||
model.chatActionEnabled = e.results[0].chat
|
||||
model.results.addAll(e.results.toList())
|
||||
List<UIResultEvent> results = e.results.toList()
|
||||
model.results.addAll(results)
|
||||
synchronized (model.allResults) {
|
||||
model.allResults.addAll(results)
|
||||
}
|
||||
model.resultCount = model.results.size()
|
||||
|
||||
int [] selectedRows = view.resultsTable.getSelectedRows()
|
||||
if (view.lastSortEvent != null) {
|
||||
for (int i = 0; i < selectedRows.length; i ++)
|
||||
selectedRows[i] = view.resultsTable.rowSorter.convertRowIndexToModel(selectedRows[i])
|
||||
view.refreshResults()
|
||||
}
|
||||
view.resultsTable.model.fireTableDataChanged()
|
||||
if (view.lastSortEvent != null) {
|
||||
for (int i = 0; i < selectedRows.length; i ++)
|
||||
selectedRows[i] = view.resultsTable.rowSorter.convertRowIndexToView(selectedRows[i])
|
||||
}
|
||||
for (int row : selectedRows)
|
||||
view.resultsTable.selectionModel.addSelectionInterval(row, row)
|
||||
|
||||
@ControllerAction
|
||||
void filter() {
|
||||
JTextField field = builder.getVariable("filter-field")
|
||||
String filter = field.getText()
|
||||
if (filter == null)
|
||||
return
|
||||
filter = filter.strip().replaceAll(SplitPattern.SPLIT_PATTERN," ").toLowerCase()
|
||||
String [] split = filter.split(" ")
|
||||
def hs = new HashSet()
|
||||
split.each {if (it.length() > 0) hs << it}
|
||||
model.filter = hs.toArray(new String[0])
|
||||
model.filterResults()
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void clearFilter() {
|
||||
model.filter = null
|
||||
model.filterResults()
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import com.muwire.core.Persona
|
||||
|
||||
import com.muwire.core.search.UIResultEvent
|
||||
import griffon.core.artifact.GriffonModel
|
||||
import griffon.inject.MVCMember
|
||||
import griffon.transform.Observable
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
|
||||
import com.muwire.core.search.BrowseStatus
|
||||
|
||||
import javax.annotation.Nonnull
|
||||
import javax.swing.SwingWorker
|
||||
|
||||
@ArtifactProviderFor(GriffonModel)
|
||||
class BrowseModel {
|
||||
@MVCMember @Nonnull
|
||||
BrowseView view
|
||||
|
||||
Persona host
|
||||
@Observable BrowseStatus status
|
||||
@Observable boolean downloadActionEnabled
|
||||
|
@ -19,7 +26,71 @@ class BrowseModel {
|
|||
@Observable boolean chatActionEnabled
|
||||
@Observable int totalResults
|
||||
@Observable int resultCount
|
||||
@Observable boolean filterEnabled
|
||||
volatile UUID uuid
|
||||
|
||||
def results = []
|
||||
List<UIResultEvent> allResults = []
|
||||
|
||||
volatile String[] filter
|
||||
volatile Filterer filterer
|
||||
|
||||
private boolean filter(UIResultEvent result) {
|
||||
if (filter == null)
|
||||
return true
|
||||
String name = result.getName().toLowerCase()
|
||||
boolean contains = true
|
||||
for (String keyword : filter) {
|
||||
contains &= name.contains(keyword)
|
||||
}
|
||||
contains
|
||||
}
|
||||
|
||||
void filterResults() {
|
||||
results.clear()
|
||||
filterer?.cancel()
|
||||
if (filter != null) {
|
||||
filterer = new Filterer()
|
||||
filterer.execute()
|
||||
} else {
|
||||
synchronized (allResults) {
|
||||
results.addAll(allResults)
|
||||
}
|
||||
view.refreshResults()
|
||||
}
|
||||
}
|
||||
|
||||
private class Filterer extends SwingWorker<List<UIResultEvent>, UIResultEvent> {
|
||||
private volatile boolean cancelled;
|
||||
|
||||
void cancel() {
|
||||
cancelled = true
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<UIResultEvent> doInBackground() throws Exception {
|
||||
synchronized (allResults) {
|
||||
for (UIResultEvent result : allResults) {
|
||||
if (cancelled)
|
||||
break
|
||||
if (filter(result))
|
||||
publish(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<UIResultEvent> chunks) {
|
||||
if (cancelled)
|
||||
return
|
||||
results.addAll(chunks)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
if (cancelled)
|
||||
return
|
||||
view.refreshResults()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import com.muwire.core.search.BrowseStatus
|
||||
import griffon.core.artifact.GriffonView
|
||||
|
||||
import javax.swing.JTextField
|
||||
|
||||
import static com.muwire.gui.Translator.trans
|
||||
import griffon.inject.MVCMember
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
|
@ -63,13 +67,25 @@ class BrowseView {
|
|||
}
|
||||
}
|
||||
panel (constraints : BorderLayout.SOUTH) {
|
||||
gridLayout(rows: 1, cols: 3)
|
||||
panel(border: etchedBorder()) {
|
||||
button(text: trans("DOWNLOAD"), enabled: bind { model.downloadActionEnabled }, downloadAction)
|
||||
label(text: trans("DOWNLOAD_SEQUENTIALLY"), enabled: bind {model.downloadActionEnabled})
|
||||
sequentialDownloadCheckbox = checkBox(enabled: bind {model.downloadActionEnabled})
|
||||
}
|
||||
panel(border: etchedBorder()) {
|
||||
button(text: trans("VIEW_COMMENT"), enabled: bind { model.viewCommentActionEnabled }, viewCommentAction)
|
||||
button(text: trans("VIEW_CERTIFICATES"), enabled: bind { model.viewCertificatesActionEnabled }, viewCertificatesAction)
|
||||
button(text: trans("VIEW_COLLECTIONS"), enabled: bind { model.viewCollectionsActionEnabled }, viewCollectionsAction)
|
||||
button(text: trans("CHAT"), enabled: bind { model.chatActionEnabled }, chatAction)
|
||||
label(text : trans("DOWNLOAD_SEQUENTIALLY"))
|
||||
sequentialDownloadCheckbox = checkBox()
|
||||
}
|
||||
panel(border: etchedBorder()) {
|
||||
def textField = new JTextField(15)
|
||||
textField.addActionListener({ controller.filter() })
|
||||
widget(id: "filter-field", enabled: bind { model.filterEnabled }, textField)
|
||||
button(text: trans("FILTER"), enabled: bind { model.filterEnabled }, filterAction)
|
||||
button(text: trans("CLEAR"), enabled: bind { model.filterEnabled }, clearFilterAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,6 +233,20 @@ class BrowseView {
|
|||
parent.setTabComponentAt(index, tabPanel)
|
||||
}
|
||||
|
||||
void refreshResults() {
|
||||
int [] selectedRows = resultsTable.getSelectedRows()
|
||||
if (lastSortEvent != null) {
|
||||
for (int i = 0; i < selectedRows.length; i ++)
|
||||
selectedRows[i] = resultsTable.rowSorter.convertRowIndexToModel(selectedRows[i])
|
||||
}
|
||||
resultsTable.model.fireTableDataChanged()
|
||||
if (lastSortEvent != null) {
|
||||
for (int i = 0; i < selectedRows.length; i ++)
|
||||
selectedRows[i] = resultsTable.rowSorter.convertRowIndexToView(selectedRows[i])
|
||||
}
|
||||
for (int row : selectedRows)
|
||||
resultsTable.selectionModel.addSelectionInterval(row, row)
|
||||
}
|
||||
|
||||
def selectedResults() {
|
||||
int [] rows = resultsTable.getSelectedRows()
|
||||
|
|
Loading…
Reference in New Issue