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
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import com.muwire.core.SplitPattern
|
||||||
import griffon.core.artifact.GriffonController
|
import griffon.core.artifact.GriffonController
|
||||||
import griffon.core.controller.ControllerAction
|
import griffon.core.controller.ControllerAction
|
||||||
import griffon.inject.MVCMember
|
import griffon.inject.MVCMember
|
||||||
|
@ -9,7 +10,6 @@ import net.i2p.data.Base64
|
||||||
import javax.annotation.Nonnull
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
import com.muwire.core.Core
|
import com.muwire.core.Core
|
||||||
import com.muwire.core.EventBus
|
|
||||||
import com.muwire.core.download.UIDownloadEvent
|
import com.muwire.core.download.UIDownloadEvent
|
||||||
import com.muwire.core.search.BrowseStatus
|
import com.muwire.core.search.BrowseStatus
|
||||||
import com.muwire.core.search.BrowseStatusEvent
|
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.UIResultBatchEvent
|
||||||
import com.muwire.core.search.UIResultEvent
|
import com.muwire.core.search.UIResultEvent
|
||||||
|
|
||||||
|
import javax.swing.JTextField
|
||||||
|
|
||||||
@ArtifactProviderFor(GriffonController)
|
@ArtifactProviderFor(GriffonController)
|
||||||
class BrowseController {
|
class BrowseController {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
FactoryBuilderSupport builder
|
||||||
@MVCMember @Nonnull
|
@MVCMember @Nonnull
|
||||||
BrowseModel model
|
BrowseModel model
|
||||||
@MVCMember @Nonnull
|
@MVCMember @Nonnull
|
||||||
|
@ -44,6 +48,8 @@ class BrowseController {
|
||||||
return
|
return
|
||||||
runInsideUIAsync {
|
runInsideUIAsync {
|
||||||
model.status = e.status
|
model.status = e.status
|
||||||
|
model.filterEnabled = (e.status == BrowseStatus.FINISHED || e.status == BrowseStatus.FAILED) &&
|
||||||
|
model.resultCount > 0
|
||||||
if (e.status == BrowseStatus.FETCHING)
|
if (e.status == BrowseStatus.FETCHING)
|
||||||
model.totalResults = e.totalResults
|
model.totalResults = e.totalResults
|
||||||
}
|
}
|
||||||
|
@ -54,25 +60,37 @@ class BrowseController {
|
||||||
if (e.uuid != model.uuid)
|
if (e.uuid != model.uuid)
|
||||||
return
|
return
|
||||||
model.chatActionEnabled = e.results[0].chat
|
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()
|
model.resultCount = model.results.size()
|
||||||
|
|
||||||
int [] selectedRows = view.resultsTable.getSelectedRows()
|
view.refreshResults()
|
||||||
if (view.lastSortEvent != null) {
|
|
||||||
for (int i = 0; i < selectedRows.length; i ++)
|
|
||||||
selectedRows[i] = view.resultsTable.rowSorter.convertRowIndexToModel(selectedRows[i])
|
|
||||||
}
|
|
||||||
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
|
@ControllerAction
|
||||||
void download() {
|
void download() {
|
||||||
def selectedResults = view.selectedResults()
|
def selectedResults = view.selectedResults()
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
package com.muwire.gui
|
package com.muwire.gui
|
||||||
|
|
||||||
import com.muwire.core.Persona
|
import com.muwire.core.Persona
|
||||||
|
import com.muwire.core.search.UIResultEvent
|
||||||
import griffon.core.artifact.GriffonModel
|
import griffon.core.artifact.GriffonModel
|
||||||
|
import griffon.inject.MVCMember
|
||||||
import griffon.transform.Observable
|
import griffon.transform.Observable
|
||||||
import griffon.metadata.ArtifactProviderFor
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
import com.muwire.core.search.BrowseStatus
|
import com.muwire.core.search.BrowseStatus
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
import javax.swing.SwingWorker
|
||||||
|
|
||||||
@ArtifactProviderFor(GriffonModel)
|
@ArtifactProviderFor(GriffonModel)
|
||||||
class BrowseModel {
|
class BrowseModel {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
BrowseView view
|
||||||
|
|
||||||
Persona host
|
Persona host
|
||||||
@Observable BrowseStatus status
|
@Observable BrowseStatus status
|
||||||
@Observable boolean downloadActionEnabled
|
@Observable boolean downloadActionEnabled
|
||||||
|
@ -19,7 +26,71 @@ class BrowseModel {
|
||||||
@Observable boolean chatActionEnabled
|
@Observable boolean chatActionEnabled
|
||||||
@Observable int totalResults
|
@Observable int totalResults
|
||||||
@Observable int resultCount
|
@Observable int resultCount
|
||||||
|
@Observable boolean filterEnabled
|
||||||
volatile UUID uuid
|
volatile UUID uuid
|
||||||
|
|
||||||
def results = []
|
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
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import com.muwire.core.search.BrowseStatus
|
||||||
import griffon.core.artifact.GriffonView
|
import griffon.core.artifact.GriffonView
|
||||||
|
|
||||||
|
import javax.swing.JTextField
|
||||||
|
|
||||||
import static com.muwire.gui.Translator.trans
|
import static com.muwire.gui.Translator.trans
|
||||||
import griffon.inject.MVCMember
|
import griffon.inject.MVCMember
|
||||||
import griffon.metadata.ArtifactProviderFor
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
@ -63,13 +67,25 @@ class BrowseView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panel (constraints : BorderLayout.SOUTH) {
|
panel (constraints : BorderLayout.SOUTH) {
|
||||||
button(text : trans("DOWNLOAD"), enabled : bind {model.downloadActionEnabled}, downloadAction)
|
gridLayout(rows: 1, cols: 3)
|
||||||
button(text : trans("VIEW_COMMENT"), enabled : bind{model.viewCommentActionEnabled}, viewCommentAction)
|
panel(border: etchedBorder()) {
|
||||||
button(text : trans("VIEW_CERTIFICATES"), enabled : bind{model.viewCertificatesActionEnabled}, viewCertificatesAction)
|
button(text: trans("DOWNLOAD"), enabled: bind { model.downloadActionEnabled }, downloadAction)
|
||||||
button(text : trans("VIEW_COLLECTIONS"), enabled : bind{model.viewCollectionsActionEnabled}, viewCollectionsAction)
|
label(text: trans("DOWNLOAD_SEQUENTIALLY"), enabled: bind {model.downloadActionEnabled})
|
||||||
button(text : trans("CHAT"), enabled : bind {model.chatActionEnabled}, chatAction)
|
sequentialDownloadCheckbox = checkBox(enabled: bind {model.downloadActionEnabled})
|
||||||
label(text : trans("DOWNLOAD_SEQUENTIALLY"))
|
}
|
||||||
sequentialDownloadCheckbox = checkBox()
|
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)
|
||||||
|
}
|
||||||
|
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)
|
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() {
|
def selectedResults() {
|
||||||
int [] rows = resultsTable.getSelectedRows()
|
int [] rows = resultsTable.getSelectedRows()
|
||||||
|
|
Loading…
Reference in New Issue