Compare commits
13 Commits
muwire-0.4
...
content-co
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ee2fd2ef68 | ||
![]() |
3f95d2bf1d | ||
![]() |
1390983732 | ||
![]() |
ce660cefe9 | ||
![]() |
72b81eb886 | ||
![]() |
57d593a68a | ||
![]() |
39a81a3376 | ||
![]() |
fd0bf17c24 | ||
![]() |
ac12bff69b | ||
![]() |
feef773bac | ||
![]() |
239d8f12a7 | ||
![]() |
8bbc61a7cb | ||
![]() |
7f31c4477f |
@@ -48,6 +48,8 @@ import com.muwire.core.trust.TrustSubscriptionEvent
|
|||||||
import com.muwire.core.update.UpdateClient
|
import com.muwire.core.update.UpdateClient
|
||||||
import com.muwire.core.upload.UploadManager
|
import com.muwire.core.upload.UploadManager
|
||||||
import com.muwire.core.util.MuWireLogManager
|
import com.muwire.core.util.MuWireLogManager
|
||||||
|
import com.muwire.core.content.ContentControlEvent
|
||||||
|
import com.muwire.core.content.ContentManager
|
||||||
|
|
||||||
import groovy.util.logging.Log
|
import groovy.util.logging.Log
|
||||||
import net.i2p.I2PAppContext
|
import net.i2p.I2PAppContext
|
||||||
@@ -90,6 +92,7 @@ public class Core {
|
|||||||
private final DirectoryWatcher directoryWatcher
|
private final DirectoryWatcher directoryWatcher
|
||||||
final FileManager fileManager
|
final FileManager fileManager
|
||||||
final UploadManager uploadManager
|
final UploadManager uploadManager
|
||||||
|
final ContentManager contentManager
|
||||||
|
|
||||||
private final Router router
|
private final Router router
|
||||||
|
|
||||||
@@ -289,6 +292,11 @@ public class Core {
|
|||||||
trustSubscriber = new TrustSubscriber(eventBus, i2pConnector, props)
|
trustSubscriber = new TrustSubscriber(eventBus, i2pConnector, props)
|
||||||
eventBus.register(UILoadedEvent.class, trustSubscriber)
|
eventBus.register(UILoadedEvent.class, trustSubscriber)
|
||||||
eventBus.register(TrustSubscriptionEvent.class, trustSubscriber)
|
eventBus.register(TrustSubscriptionEvent.class, trustSubscriber)
|
||||||
|
|
||||||
|
log.info("initializing content manager")
|
||||||
|
contentManager = new ContentManager()
|
||||||
|
eventBus.register(ContentControlEvent.class, contentManager)
|
||||||
|
eventBus.register(QueryEvent.class, contentManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startServices() {
|
public void startServices() {
|
||||||
|
@@ -48,4 +48,9 @@ class EventBus {
|
|||||||
}
|
}
|
||||||
currentHandlers.add handler
|
currentHandlers.add handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized void unregister(Class<? extends Event> eventType, def handler) {
|
||||||
|
log.info("Unregistering $handler for type $eventType")
|
||||||
|
handlers[eventType]?.remove(handler)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,8 @@ class MuWireSettings {
|
|||||||
int meshExpiration
|
int meshExpiration
|
||||||
boolean embeddedRouter
|
boolean embeddedRouter
|
||||||
int inBw, outBw
|
int inBw, outBw
|
||||||
|
Set<String> watchedKeywords
|
||||||
|
Set<String> watchedRegexes
|
||||||
|
|
||||||
MuWireSettings() {
|
MuWireSettings() {
|
||||||
this(new Properties())
|
this(new Properties())
|
||||||
@@ -54,11 +56,9 @@ class MuWireSettings {
|
|||||||
inBw = Integer.valueOf(props.getProperty("inBw","256"))
|
inBw = Integer.valueOf(props.getProperty("inBw","256"))
|
||||||
outBw = Integer.valueOf(props.getProperty("outBw","128"))
|
outBw = Integer.valueOf(props.getProperty("outBw","128"))
|
||||||
|
|
||||||
watchedDirectories = new HashSet<>()
|
watchedDirectories = readEncodedSet(props, "watchedDirectories")
|
||||||
if (props.containsKey("watchedDirectories")) {
|
watchedKeywords = readEncodedSet(props, "watchedKeywords")
|
||||||
String[] encoded = props.getProperty("watchedDirectories").split(",")
|
watchedRegexes = readEncodedSet(props, "watchedRegexes")
|
||||||
encoded.each { watchedDirectories << DataUtil.readi18nString(Base64.decode(it)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
trustSubscriptions = new HashSet<>()
|
trustSubscriptions = new HashSet<>()
|
||||||
if (props.containsKey("trustSubscriptions")) {
|
if (props.containsKey("trustSubscriptions")) {
|
||||||
@@ -66,6 +66,8 @@ class MuWireSettings {
|
|||||||
trustSubscriptions.add(new Persona(new ByteArrayInputStream(Base64.decode(it))))
|
trustSubscriptions.add(new Persona(new ByteArrayInputStream(Base64.decode(it))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(OutputStream out) throws IOException {
|
void write(OutputStream out) throws IOException {
|
||||||
@@ -89,12 +91,9 @@ class MuWireSettings {
|
|||||||
props.setProperty("inBw", String.valueOf(inBw))
|
props.setProperty("inBw", String.valueOf(inBw))
|
||||||
props.setProperty("outBw", String.valueOf(outBw))
|
props.setProperty("outBw", String.valueOf(outBw))
|
||||||
|
|
||||||
if (!watchedDirectories.isEmpty()) {
|
writeEncodedSet(watchedDirectories, "watchedDirectories", props)
|
||||||
String encoded = watchedDirectories.stream().
|
writeEncodedSet(watchedKeywords, "watchedKeywords", props)
|
||||||
map({Base64.encode(DataUtil.encodei18nString(it))}).
|
writeEncodedSet(watchedRegexes, "watchedRegexes", props)
|
||||||
collect(Collectors.joining(","))
|
|
||||||
props.setProperty("watchedDirectories", encoded)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!trustSubscriptions.isEmpty()) {
|
if (!trustSubscriptions.isEmpty()) {
|
||||||
String encoded = trustSubscriptions.stream().
|
String encoded = trustSubscriptions.stream().
|
||||||
@@ -105,6 +104,24 @@ class MuWireSettings {
|
|||||||
|
|
||||||
props.store(out, "")
|
props.store(out, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<String> readEncodedSet(Properties props, String property) {
|
||||||
|
Set<String> rv = new HashSet<>()
|
||||||
|
if (props.containsKey(property)) {
|
||||||
|
String[] encoded = props.getProperty(property).split(",")
|
||||||
|
encoded.each { rv << DataUtil.readi18nString(Base64.decode(it)) }
|
||||||
|
}
|
||||||
|
rv
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeEncodedSet(Set<String> set, String property, Properties props) {
|
||||||
|
if (set.isEmpty())
|
||||||
|
return
|
||||||
|
String encoded = set.stream().
|
||||||
|
map({Base64.encode(DataUtil.encodei18nString(it))}).
|
||||||
|
collect(Collectors.joining(","))
|
||||||
|
props.setProperty(property, encoded)
|
||||||
|
}
|
||||||
|
|
||||||
boolean isLeaf() {
|
boolean isLeaf() {
|
||||||
isLeaf
|
isLeaf
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
import com.muwire.core.Event
|
||||||
|
|
||||||
|
class ContentControlEvent extends Event {
|
||||||
|
String term
|
||||||
|
boolean regex
|
||||||
|
boolean add
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
import com.muwire.core.search.QueryEvent
|
||||||
|
|
||||||
|
import net.i2p.util.ConcurrentHashSet
|
||||||
|
|
||||||
|
class ContentManager {
|
||||||
|
|
||||||
|
Set<Matcher> matchers = new ConcurrentHashSet()
|
||||||
|
|
||||||
|
void onContentControlEvent(ContentControlEvent e) {
|
||||||
|
Matcher m
|
||||||
|
if (e.regex)
|
||||||
|
m = new RegexMatcher(e.term)
|
||||||
|
else
|
||||||
|
m = new KeywordMatcher(e.term)
|
||||||
|
if (e.add)
|
||||||
|
matchers.add(m)
|
||||||
|
else
|
||||||
|
matchers.remove(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
void onQueryEvent(QueryEvent e) {
|
||||||
|
if (e.searchEvent.searchTerms == null)
|
||||||
|
return
|
||||||
|
matchers.each { it.process(e) }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
class KeywordMatcher extends Matcher {
|
||||||
|
private final String keyword
|
||||||
|
KeywordMatcher(String keyword) {
|
||||||
|
this.keyword = keyword
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean match(List<String> searchTerms) {
|
||||||
|
boolean found = false
|
||||||
|
searchTerms.each {
|
||||||
|
if (keyword == it)
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
found
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTerm() {
|
||||||
|
keyword
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
keyword.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof KeywordMatcher))
|
||||||
|
return false
|
||||||
|
KeywordMatcher other = (KeywordMatcher) o
|
||||||
|
keyword.equals(other.keyword)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
import com.muwire.core.Persona
|
||||||
|
|
||||||
|
class Match {
|
||||||
|
Persona persona
|
||||||
|
String [] keywords
|
||||||
|
long timestamp
|
||||||
|
}
|
20
core/src/main/groovy/com/muwire/core/content/Matcher.groovy
Normal file
20
core/src/main/groovy/com/muwire/core/content/Matcher.groovy
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
import com.muwire.core.search.QueryEvent
|
||||||
|
|
||||||
|
abstract class Matcher {
|
||||||
|
final List<Match> matches = Collections.synchronizedList(new ArrayList<>())
|
||||||
|
final Set<UUID> uuids = new HashSet<>()
|
||||||
|
|
||||||
|
protected abstract boolean match(List<String> searchTerms);
|
||||||
|
|
||||||
|
public abstract String getTerm();
|
||||||
|
|
||||||
|
public void process(QueryEvent qe) {
|
||||||
|
def terms = qe.searchEvent.searchTerms
|
||||||
|
if (match(terms) && uuids.add(qe.searchEvent.uuid)) {
|
||||||
|
long now = System.currentTimeMillis()
|
||||||
|
matches << new Match(persona : qe.originator, keywords : terms, timestamp : now)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
package com.muwire.core.content
|
||||||
|
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
|
class RegexMatcher extends Matcher {
|
||||||
|
private final Pattern pattern
|
||||||
|
RegexMatcher(String pattern) {
|
||||||
|
this.pattern = Pattern.compile(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean match(List<String> keywords) {
|
||||||
|
String combined = keywords.join(" ")
|
||||||
|
return pattern.matcher(combined).find()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTerm() {
|
||||||
|
pattern.pattern()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
pattern.pattern().hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof RegexMatcher))
|
||||||
|
return false
|
||||||
|
RegexMatcher other = (RegexMatcher) o
|
||||||
|
pattern.pattern() == other.pattern.pattern()
|
||||||
|
}
|
||||||
|
}
|
@@ -41,4 +41,9 @@ mvcGroups {
|
|||||||
view = 'com.muwire.gui.TrustListView'
|
view = 'com.muwire.gui.TrustListView'
|
||||||
controller = 'com.muwire.gui.TrustListController'
|
controller = 'com.muwire.gui.TrustListController'
|
||||||
}
|
}
|
||||||
|
'content-panel' {
|
||||||
|
model = 'com.muwire.gui.ContentPanelModel'
|
||||||
|
view = 'com.muwire.gui.ContentPanelView'
|
||||||
|
controller = 'com.muwire.gui.ContentPanelController'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,95 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonController
|
||||||
|
import griffon.core.controller.ControllerAction
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
import com.muwire.core.EventBus
|
||||||
|
import com.muwire.core.content.ContentControlEvent
|
||||||
|
import com.muwire.core.content.Match
|
||||||
|
import com.muwire.core.content.Matcher
|
||||||
|
import com.muwire.core.content.RegexMatcher
|
||||||
|
import com.muwire.core.trust.TrustEvent
|
||||||
|
import com.muwire.core.trust.TrustLevel
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonController)
|
||||||
|
class ContentPanelController {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
ContentPanelModel model
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
ContentPanelView view
|
||||||
|
|
||||||
|
Core core
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void addRule() {
|
||||||
|
def term = view.ruleTextField.text
|
||||||
|
|
||||||
|
if (model.regex)
|
||||||
|
core.muOptions.watchedRegexes.add(term)
|
||||||
|
else
|
||||||
|
core.muOptions.watchedKeywords.add(term)
|
||||||
|
saveMuWireSettings()
|
||||||
|
|
||||||
|
core.eventBus.publish(new ContentControlEvent(term : term, regex : model.regex, add:true))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void deleteRule() {
|
||||||
|
int rule = view.getSelectedRule()
|
||||||
|
if (rule < 0)
|
||||||
|
return
|
||||||
|
Matcher matcher = model.rules[rule]
|
||||||
|
String term = matcher.getTerm()
|
||||||
|
if (matcher instanceof RegexMatcher)
|
||||||
|
core.muOptions.watchedRegexes.remove(term)
|
||||||
|
else
|
||||||
|
core.muOptions.watchedKeywords.remove(term)
|
||||||
|
saveMuWireSettings()
|
||||||
|
|
||||||
|
core.eventBus.publish(new ContentControlEvent(term : term, regex : (matcher instanceof RegexMatcher), add: false))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void keyword() {
|
||||||
|
model.regex = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void regex() {
|
||||||
|
model.regex = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void refresh() {
|
||||||
|
model.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void trust() {
|
||||||
|
int selectedHit = view.getSelectedHit()
|
||||||
|
if (selectedHit < 0)
|
||||||
|
return
|
||||||
|
Match m = model.hits[selectedHit]
|
||||||
|
core.eventBus.publish(new TrustEvent(persona : m.persona, level : TrustLevel.TRUSTED))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void distrust() {
|
||||||
|
int selectedHit = view.getSelectedHit()
|
||||||
|
if (selectedHit < 0)
|
||||||
|
return
|
||||||
|
Match m = model.hits[selectedHit]
|
||||||
|
core.eventBus.publish(new TrustEvent(persona : m.persona, level : TrustLevel.DISTRUSTED))
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveMuWireSettings() {
|
||||||
|
File f = new File(core.home, "MuWire.properties")
|
||||||
|
f.withOutputStream {
|
||||||
|
core.muOptions.write(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
import com.muwire.core.EventBus
|
||||||
|
import com.muwire.core.content.ContentControlEvent
|
||||||
|
import com.muwire.core.content.ContentManager
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonModel
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.transform.Observable
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonModel)
|
||||||
|
class ContentPanelModel {
|
||||||
|
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
ContentPanelView view
|
||||||
|
|
||||||
|
Core core
|
||||||
|
|
||||||
|
private ContentManager contentManager
|
||||||
|
|
||||||
|
def rules = []
|
||||||
|
def hits = []
|
||||||
|
|
||||||
|
@Observable boolean regex
|
||||||
|
@Observable boolean deleteButtonEnabled
|
||||||
|
@Observable boolean trustButtonsEnabled
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
contentManager = application.context.get("core").contentManager
|
||||||
|
rules.addAll(contentManager.matchers)
|
||||||
|
core.eventBus.register(ContentControlEvent.class, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
void mvcGroupDestroy() {
|
||||||
|
core.eventBus.unregister(ContentControlEvent.class, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh() {
|
||||||
|
rules.clear()
|
||||||
|
rules.addAll(contentManager.matchers)
|
||||||
|
hits.clear()
|
||||||
|
view.rulesTable.model.fireTableDataChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
void onContentControlEvent(ContentControlEvent e) {
|
||||||
|
runInsideUIAsync {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,7 @@ import com.muwire.core.RouterDisconnectedEvent
|
|||||||
import com.muwire.core.connection.ConnectionAttemptStatus
|
import com.muwire.core.connection.ConnectionAttemptStatus
|
||||||
import com.muwire.core.connection.ConnectionEvent
|
import com.muwire.core.connection.ConnectionEvent
|
||||||
import com.muwire.core.connection.DisconnectionEvent
|
import com.muwire.core.connection.DisconnectionEvent
|
||||||
|
import com.muwire.core.content.ContentControlEvent
|
||||||
import com.muwire.core.download.DownloadStartedEvent
|
import com.muwire.core.download.DownloadStartedEvent
|
||||||
import com.muwire.core.download.Downloader
|
import com.muwire.core.download.Downloader
|
||||||
import com.muwire.core.files.AllFilesLoadedEvent
|
import com.muwire.core.files.AllFilesLoadedEvent
|
||||||
@@ -164,6 +165,13 @@ class MainFrameModel {
|
|||||||
core.eventBus.register(UpdateDownloadedEvent.class, this)
|
core.eventBus.register(UpdateDownloadedEvent.class, this)
|
||||||
core.eventBus.register(TrustSubscriptionUpdatedEvent.class, this)
|
core.eventBus.register(TrustSubscriptionUpdatedEvent.class, this)
|
||||||
|
|
||||||
|
core.muOptions.watchedKeywords.each {
|
||||||
|
core.eventBus.publish(new ContentControlEvent(term : it, regex: false, add: true))
|
||||||
|
}
|
||||||
|
core.muOptions.watchedRegexes.each {
|
||||||
|
core.eventBus.publish(new ContentControlEvent(term : it, regex: true, add: true))
|
||||||
|
}
|
||||||
|
|
||||||
timer.schedule({
|
timer.schedule({
|
||||||
if (core.shutdown.get())
|
if (core.shutdown.get())
|
||||||
return
|
return
|
||||||
|
144
gui/griffon-app/views/com/muwire/gui/ContentPanelView.groovy
Normal file
144
gui/griffon-app/views/com/muwire/gui/ContentPanelView.groovy
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonView
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
import javax.swing.JDialog
|
||||||
|
import javax.swing.ListSelectionModel
|
||||||
|
import javax.swing.SwingConstants
|
||||||
|
|
||||||
|
import com.muwire.core.content.Matcher
|
||||||
|
import com.muwire.core.content.RegexMatcher
|
||||||
|
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.event.WindowAdapter
|
||||||
|
import java.awt.event.WindowEvent
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonView)
|
||||||
|
class ContentPanelView {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
FactoryBuilderSupport builder
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
ContentPanelModel model
|
||||||
|
|
||||||
|
def dialog
|
||||||
|
def mainFrame
|
||||||
|
def mainPanel
|
||||||
|
|
||||||
|
def rulesTable
|
||||||
|
def ruleTextField
|
||||||
|
def lastRulesSortEvent
|
||||||
|
def hitsTable
|
||||||
|
def lastHitsSortEvent
|
||||||
|
|
||||||
|
void initUI() {
|
||||||
|
mainFrame = application.windowManager.findWindow("main-frame")
|
||||||
|
dialog = new JDialog(mainFrame, "Content Control Panel", true)
|
||||||
|
|
||||||
|
mainPanel = builder.panel {
|
||||||
|
gridLayout(rows:2, cols:1)
|
||||||
|
panel {
|
||||||
|
borderLayout()
|
||||||
|
scrollPane (constraints : BorderLayout.CENTER) {
|
||||||
|
rulesTable = table(id : "rules-table", autoCreateRowSorter : true) {
|
||||||
|
tableModel(list : model.rules) {
|
||||||
|
closureColumn(header: "Term", type:String, read: {row -> row.getTerm()})
|
||||||
|
closureColumn(header: "Regex?", type:Boolean, read: {row -> row instanceof RegexMatcher})
|
||||||
|
closureColumn(header: "Hits", type:Integer, read : {row -> row.matches.size()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panel (constraints : BorderLayout.SOUTH) {
|
||||||
|
borderLayout()
|
||||||
|
ruleTextField = textField(constraints: BorderLayout.CENTER, action: addRuleAction)
|
||||||
|
panel (constraints: BorderLayout.EAST) {
|
||||||
|
buttonGroup(id : "ruleType")
|
||||||
|
radioButton(text: "Keyword", selected : true, buttonGroup: ruleType, keywordAction)
|
||||||
|
radioButton(text: "Regex", selected : false, buttonGroup: ruleType, regexAction)
|
||||||
|
button(text : "Add Rule", addRuleAction)
|
||||||
|
button(text : "Delete Rule", enabled : bind {model.deleteButtonEnabled}, deleteRuleAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panel {
|
||||||
|
borderLayout()
|
||||||
|
scrollPane(constraints : BorderLayout.CENTER) {
|
||||||
|
hitsTable = table(id : "hits-table", autoCreateRowSorter : true) {
|
||||||
|
tableModel(list : model.hits) {
|
||||||
|
closureColumn(header : "Searcher", type : String, read : {row -> row.persona.getHumanReadableName()})
|
||||||
|
closureColumn(header : "Keywords", type : String, read : {row -> row.keywords.join(" ")})
|
||||||
|
closureColumn(header : "Date", type : String, read : {row -> String.valueOf(new Date(row.timestamp))})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panel (constraints : BorderLayout.SOUTH) {
|
||||||
|
button(text : "Refresh", refreshAction)
|
||||||
|
button(text : "Trust", enabled : bind {model.trustButtonsEnabled}, trustAction)
|
||||||
|
button(text : "Distrust", enabled : bind {model.trustButtonsEnabled}, distrustAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSelectedRule() {
|
||||||
|
int selectedRow = rulesTable.getSelectedRow()
|
||||||
|
if (selectedRow < 0)
|
||||||
|
return -1
|
||||||
|
if (lastRulesSortEvent != null)
|
||||||
|
selectedRow = rulesTable.rowSorter.convertRowIndexToModel(selectedRow)
|
||||||
|
selectedRow
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSelectedHit() {
|
||||||
|
int selectedRow = hitsTable.getSelectedRow()
|
||||||
|
if (selectedRow < 0)
|
||||||
|
return -1
|
||||||
|
if (lastHitsSortEvent != null)
|
||||||
|
selectedRow = hitsTable.rowSorter.convertRowIndexToModel(selectedRow)
|
||||||
|
selectedRow
|
||||||
|
}
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
|
||||||
|
rulesTable.rowSorter.addRowSorterListener({evt -> lastRulesSortEvent = evt})
|
||||||
|
rulesTable.rowSorter.setSortsOnUpdates(true)
|
||||||
|
def selectionModel = rulesTable.getSelectionModel()
|
||||||
|
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
|
||||||
|
selectionModel.addListSelectionListener({
|
||||||
|
int selectedRow = getSelectedRule()
|
||||||
|
if (selectedRow < 0) {
|
||||||
|
model.deleteButtonEnabled = false
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
model.deleteButtonEnabled = true
|
||||||
|
model.hits.clear()
|
||||||
|
Matcher matcher = model.rules[selectedRow]
|
||||||
|
model.hits.addAll(matcher.matches)
|
||||||
|
hitsTable.model.fireTableDataChanged()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
hitsTable.rowSorter.addRowSorterListener({evt -> lastHitsSortEvent = evt})
|
||||||
|
hitsTable.rowSorter.setSortsOnUpdates(true)
|
||||||
|
selectionModel = hitsTable.getSelectionModel()
|
||||||
|
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
|
||||||
|
selectionModel.addListSelectionListener({
|
||||||
|
int selectedRow = getSelectedHit()
|
||||||
|
model.trustButtonsEnabled = selectedRow >= 0
|
||||||
|
})
|
||||||
|
|
||||||
|
dialog.getContentPane().add(mainPanel)
|
||||||
|
dialog.pack()
|
||||||
|
dialog.setLocationRelativeTo(mainFrame)
|
||||||
|
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
|
||||||
|
dialog.addWindowListener(new WindowAdapter() {
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
mvcGroup.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
}
|
@@ -72,6 +72,11 @@ class MainFrameView {
|
|||||||
menuBar {
|
menuBar {
|
||||||
menu (text : "Options") {
|
menu (text : "Options") {
|
||||||
menuItem("Configuration", actionPerformed : {mvcGroup.createMVCGroup("Options")})
|
menuItem("Configuration", actionPerformed : {mvcGroup.createMVCGroup("Options")})
|
||||||
|
menuItem("Content Control", actionPerformed : {
|
||||||
|
def env = [:]
|
||||||
|
env["core"] = model.core
|
||||||
|
mvcGroup.createMVCGroup("content-panel", env)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
menu (text : "Status") {
|
menu (text : "Status") {
|
||||||
menuItem("MuWire", actionPerformed : {mvcGroup.createMVCGroup("mu-wire-status")})
|
menuItem("MuWire", actionPerformed : {mvcGroup.createMVCGroup("mu-wire-status")})
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonFestRule
|
||||||
|
import org.fest.swing.fixture.FrameFixture
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
class ContentPanelIntegrationTest {
|
||||||
|
static {
|
||||||
|
System.setProperty('griffon.swing.edt.violations.check', 'true')
|
||||||
|
System.setProperty('griffon.swing.edt.hang.monitor', 'true')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonFestRule fest = new GriffonFestRule()
|
||||||
|
|
||||||
|
private FrameFixture window
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not implemented yet!')
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonUnitRule
|
||||||
|
import griffon.core.test.TestFor
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
@TestFor(ContentPanelController)
|
||||||
|
class ContentPanelControllerTest {
|
||||||
|
private ContentPanelController controller
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonUnitRule griffon = new GriffonUnitRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not yet implemented!')
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user