Tree view of the shared files. The count is wrong for some reason
This commit is contained in:
BIN
gui/griffon-app/.DS_Store
vendored
Normal file
BIN
gui/griffon-app/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -27,7 +27,7 @@ class AddCommentController {
|
||||
model.selectedFiles.each {
|
||||
it.setComment(comment)
|
||||
}
|
||||
mvcGroup.parentGroup.view.builder.getVariable("shared-files-table").model.fireTableDataChanged()
|
||||
mvcGroup.parentGroup.view.refreshSharedFiles()
|
||||
cancel()
|
||||
}
|
||||
|
||||
|
@@ -143,6 +143,8 @@ class OptionsController {
|
||||
// boolean showSearchHashes = view.showSearchHashesCheckbox.model.isSelected()
|
||||
// model.showSearchHashes = showSearchHashes
|
||||
// uiSettings.showSearchHashes = showSearchHashes
|
||||
|
||||
uiSettings.sharedFilesAsTree = model.sharedFilesAsTree
|
||||
|
||||
File uiSettingsFile = new File(core.home, "gui.properties")
|
||||
uiSettingsFile.withOutputStream {
|
||||
@@ -168,4 +170,14 @@ class OptionsController {
|
||||
if (rv == JFileChooser.APPROVE_OPTION)
|
||||
model.downloadLocation = chooser.getSelectedFile().getAbsolutePath()
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void sharedTree() {
|
||||
model.sharedFilesAsTree = true
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void sharedTable() {
|
||||
model.sharedFilesAsTree = false
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package com.muwire.gui
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.nio.file.Path
|
||||
import java.util.Calendar
|
||||
import java.util.UUID
|
||||
|
||||
@@ -8,12 +9,16 @@ import javax.annotation.Nonnull
|
||||
import javax.inject.Inject
|
||||
import javax.swing.JOptionPane
|
||||
import javax.swing.JTable
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
import javax.swing.tree.DefaultTreeModel
|
||||
import javax.swing.tree.TreeNode
|
||||
|
||||
import com.muwire.core.Core
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.MuWireSettings
|
||||
import com.muwire.core.Persona
|
||||
import com.muwire.core.RouterDisconnectedEvent
|
||||
import com.muwire.core.SharedFile
|
||||
import com.muwire.core.connection.ConnectionAttemptStatus
|
||||
import com.muwire.core.connection.ConnectionEvent
|
||||
import com.muwire.core.connection.DisconnectionEvent
|
||||
@@ -57,6 +62,8 @@ class MainFrameModel {
|
||||
FactoryBuilderSupport builder
|
||||
@MVCMember @Nonnull
|
||||
MainFrameController controller
|
||||
@MVCMember @Nonnull
|
||||
MainFrameView view
|
||||
@Inject @Nonnull GriffonApplication application
|
||||
@Observable boolean coreInitialized = false
|
||||
@Observable boolean routerPresent
|
||||
@@ -64,7 +71,10 @@ class MainFrameModel {
|
||||
def results = new ConcurrentHashMap<>()
|
||||
def downloads = []
|
||||
def uploads = []
|
||||
def shared = []
|
||||
def shared
|
||||
def sharedTree
|
||||
def treeRoot
|
||||
final Map<SharedFile, TreeNode> fileToNode = new HashMap<>()
|
||||
def watched = []
|
||||
def connectionList = []
|
||||
def searches = new LinkedList()
|
||||
@@ -122,6 +132,13 @@ class MainFrameModel {
|
||||
void mvcGroupInit(Map<String, Object> args) {
|
||||
|
||||
uiSettings = application.context.get("ui-settings")
|
||||
|
||||
if (!uiSettings.sharedFilesAsTree)
|
||||
shared = []
|
||||
else {
|
||||
treeRoot = new DefaultMutableTreeNode()
|
||||
sharedTree = new DefaultTreeModel(treeRoot)
|
||||
}
|
||||
|
||||
Timer timer = new Timer("download-pumper", true)
|
||||
timer.schedule({
|
||||
@@ -303,7 +320,6 @@ class MainFrameModel {
|
||||
|
||||
void onFileHashingEvent(FileHashingEvent e) {
|
||||
runInsideUIAsync {
|
||||
loadedFiles = shared.size()
|
||||
hashingFile = e.hashingFile
|
||||
}
|
||||
}
|
||||
@@ -315,28 +331,53 @@ class MainFrameModel {
|
||||
if (e.error != null)
|
||||
return // TODO do something
|
||||
runInsideUIAsync {
|
||||
shared << e.sharedFile
|
||||
loadedFiles = shared.size()
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
if (!uiSettings.sharedFilesAsTree) {
|
||||
shared << e.sharedFile
|
||||
loadedFiles = shared.size()
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
} else {
|
||||
insertIntoTree(e.sharedFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onFileLoadedEvent(FileLoadedEvent e) {
|
||||
runInsideUIAsync {
|
||||
shared << e.loadedFile
|
||||
loadedFiles = shared.size()
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
if (!uiSettings.sharedFilesAsTree) {
|
||||
shared << e.loadedFile
|
||||
loadedFiles = shared.size()
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
} else {
|
||||
insertIntoTree(e.loadedFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onFileUnsharedEvent(FileUnsharedEvent e) {
|
||||
runInsideUIAsync {
|
||||
shared.remove(e.unsharedFile)
|
||||
loadedFiles = shared.size()
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
if (!uiSettings.sharedFilesAsTree) {
|
||||
shared.remove(e.unsharedFile)
|
||||
loadedFiles = shared.size()
|
||||
} else {
|
||||
def dmtn = fileToNode.remove(e.unsharedFile)
|
||||
if (dmtn != null) {
|
||||
loadedFiles = fileToNode.size()
|
||||
while (true) {
|
||||
def parent = dmtn.getParent()
|
||||
parent.remove(dmtn)
|
||||
if (parent == treeRoot)
|
||||
break
|
||||
if (parent.getChildCount() == 0) {
|
||||
dmtn = parent
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
view.refreshSharedFiles()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,11 +517,44 @@ class MainFrameModel {
|
||||
if (!core.muOptions.shareDownloadedFiles)
|
||||
return
|
||||
runInsideUIAsync {
|
||||
shared << e.downloadedFile
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
if (!uiSettings.sharedFilesAsTree) {
|
||||
shared << e.downloadedFile
|
||||
JTable table = builder.getVariable("shared-files-table")
|
||||
table.model.fireTableDataChanged()
|
||||
} else {
|
||||
insertIntoTree(e.downloadedFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void insertIntoTree(SharedFile file) {
|
||||
Path folder = file.getFile().toPath()
|
||||
folder = folder.subpath(0, folder.getNameCount() - 1)
|
||||
TreeNode node = treeRoot
|
||||
for(Path path : folder) {
|
||||
boolean exists = false
|
||||
def children = node.children()
|
||||
def child = null
|
||||
while(children.hasMoreElements()) {
|
||||
child = children.nextElement()
|
||||
if (child.getUserObject() == path.toString()) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!exists) {
|
||||
child = new DefaultMutableTreeNode(path.toString())
|
||||
node.add(child)
|
||||
}
|
||||
node = child
|
||||
}
|
||||
|
||||
def dmtn = new DefaultMutableTreeNode(file)
|
||||
fileToNode[file] = dmtn
|
||||
node.add(dmtn)
|
||||
loadedFiles = fileToNode.size()
|
||||
view.refreshSharedFiles()
|
||||
}
|
||||
|
||||
private static class UIConnection {
|
||||
Destination destination
|
||||
|
@@ -31,6 +31,7 @@ class OptionsModel {
|
||||
@Observable boolean clearFinishedDownloads
|
||||
@Observable boolean excludeLocalResult
|
||||
@Observable boolean showSearchHashes
|
||||
@Observable boolean sharedFilesAsTree
|
||||
|
||||
// bw options
|
||||
@Observable String inBw
|
||||
@@ -67,6 +68,7 @@ class OptionsModel {
|
||||
clearFinishedDownloads = uiSettings.clearFinishedDownloads
|
||||
excludeLocalResult = uiSettings.excludeLocalResult
|
||||
showSearchHashes = uiSettings.showSearchHashes
|
||||
sharedFilesAsTree = uiSettings.sharedFilesAsTree
|
||||
|
||||
if (core.router != null) {
|
||||
inBw = String.valueOf(settings.inBw)
|
||||
|
BIN
gui/griffon-app/resources/comment.png
Normal file
BIN
gui/griffon-app/resources/comment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 598 B |
@@ -16,11 +16,14 @@ import javax.swing.JMenuItem
|
||||
import javax.swing.JPopupMenu
|
||||
import javax.swing.JSplitPane
|
||||
import javax.swing.JTable
|
||||
import javax.swing.JTree
|
||||
import javax.swing.ListSelectionModel
|
||||
import javax.swing.SwingConstants
|
||||
import javax.swing.TransferHandler
|
||||
import javax.swing.border.Border
|
||||
import javax.swing.table.DefaultTableCellRenderer
|
||||
import javax.swing.tree.TreeNode
|
||||
import javax.swing.tree.TreePath
|
||||
|
||||
import com.muwire.core.Constants
|
||||
import com.muwire.core.MuWireSettings
|
||||
@@ -59,8 +62,10 @@ class MainFrameView {
|
||||
def lastWatchedSortEvent
|
||||
def trustTablesSortEvents = [:]
|
||||
|
||||
UISettings settings
|
||||
|
||||
void initUI() {
|
||||
UISettings settings = application.context.get("ui-settings")
|
||||
settings = application.context.get("ui-settings")
|
||||
builder.with {
|
||||
application(size : [1024,768], id: 'main-frame',
|
||||
locationRelativeTo : null,
|
||||
@@ -207,12 +212,18 @@ class MainFrameView {
|
||||
panel {
|
||||
borderLayout()
|
||||
scrollPane(constraints : BorderLayout.CENTER) {
|
||||
table(id : "shared-files-table", autoCreateRowSorter: true) {
|
||||
tableModel(list : model.shared) {
|
||||
closureColumn(header : "Name", preferredWidth : 500, type : String, read : {row -> row.getCachedPath()})
|
||||
closureColumn(header : "Size", preferredWidth : 100, type : Long, read : {row -> row.getCachedLength() })
|
||||
closureColumn(header : "Comments", preferredWidth : 100, type : Boolean, read : {it.getComment() != null})
|
||||
if (!settings.sharedFilesAsTree) {
|
||||
table(id : "shared-files-table", autoCreateRowSorter: true) {
|
||||
tableModel(list : model.shared) {
|
||||
closureColumn(header : "Name", preferredWidth : 500, type : String, read : {row -> row.getCachedPath()})
|
||||
closureColumn(header : "Size", preferredWidth : 100, type : Long, read : {row -> row.getCachedLength() })
|
||||
closureColumn(header : "Comments", preferredWidth : 100, type : Boolean, read : {it.getComment() != null})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
def jtree = new JTree(model.sharedTree)
|
||||
jtree.setCellRenderer(new SharedTreeRenderer())
|
||||
tree(id : "shared-files-tree", rootVisible : false, jtree)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,7 +238,7 @@ class MainFrameView {
|
||||
gridLayout(rows : 1, cols : 2)
|
||||
panel {
|
||||
label("Shared:")
|
||||
label(text : bind {model.loadedFiles.toString()})
|
||||
label(text : bind {model.loadedFiles}, id : "shared-files-count")
|
||||
}
|
||||
panel {
|
||||
button(text : "Add Comment", enabled : bind {model.addCommentButtonEnabled}, addCommentAction)
|
||||
@@ -489,13 +500,7 @@ class MainFrameView {
|
||||
}
|
||||
})
|
||||
|
||||
// shared files table
|
||||
def sharedFilesTable = builder.getVariable("shared-files-table")
|
||||
sharedFilesTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer())
|
||||
|
||||
sharedFilesTable.rowSorter.addRowSorterListener({evt -> lastSharedSortEvent = evt})
|
||||
sharedFilesTable.rowSorter.setSortsOnUpdates(true)
|
||||
|
||||
// shared files menu
|
||||
JPopupMenu sharedFilesMenu = new JPopupMenu()
|
||||
JMenuItem copyHashToClipboard = new JMenuItem("Copy hash to clipboard")
|
||||
copyHashToClipboard.addActionListener({mvcGroup.view.copyHashToClipboard()})
|
||||
@@ -506,7 +511,8 @@ class MainFrameView {
|
||||
JMenuItem commentSelectedFiles = new JMenuItem("Comment selected files")
|
||||
commentSelectedFiles.addActionListener({mvcGroup.controller.addComment()})
|
||||
sharedFilesMenu.add(commentSelectedFiles)
|
||||
sharedFilesTable.addMouseListener(new MouseAdapter() {
|
||||
|
||||
def sharedFilesMouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.isPopupTrigger())
|
||||
@@ -517,15 +523,36 @@ class MainFrameView {
|
||||
if (e.isPopupTrigger())
|
||||
showPopupMenu(sharedFilesMenu, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
selectionModel = sharedFilesTable.getSelectionModel()
|
||||
selectionModel.addListSelectionListener({
|
||||
def selectedFiles = selectedSharedFiles()
|
||||
if (selectedFiles == null || selectedFiles.isEmpty())
|
||||
return
|
||||
model.addCommentButtonEnabled = true
|
||||
})
|
||||
// shared files table or tree
|
||||
if (!settings.sharedFilesAsTree) {
|
||||
def sharedFilesTable = builder.getVariable("shared-files-table")
|
||||
sharedFilesTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer())
|
||||
|
||||
sharedFilesTable.rowSorter.addRowSorterListener({evt -> lastSharedSortEvent = evt})
|
||||
sharedFilesTable.rowSorter.setSortsOnUpdates(true)
|
||||
|
||||
sharedFilesTable.addMouseListener(sharedFilesMouseListener)
|
||||
|
||||
selectionModel = sharedFilesTable.getSelectionModel()
|
||||
selectionModel.addListSelectionListener({
|
||||
def selectedFiles = selectedSharedFiles()
|
||||
if (selectedFiles == null || selectedFiles.isEmpty())
|
||||
return
|
||||
model.addCommentButtonEnabled = true
|
||||
})
|
||||
} else {
|
||||
def sharedFilesTree = builder.getVariable("shared-files-tree")
|
||||
sharedFilesTree.addMouseListener(sharedFilesMouseListener)
|
||||
|
||||
sharedFilesTree.addTreeSelectionListener({
|
||||
def selectedNode = sharedFilesTree.getLastSelectedPathComponent()
|
||||
model.addCommentButtonEnabled = selectedNode != null
|
||||
|
||||
})
|
||||
// TODO: other stuff
|
||||
}
|
||||
|
||||
// searches table
|
||||
def searchesTable = builder.getVariable("searches-table")
|
||||
@@ -656,20 +683,40 @@ class MainFrameView {
|
||||
}
|
||||
|
||||
def selectedSharedFiles() {
|
||||
def sharedFilesTable = builder.getVariable("shared-files-table")
|
||||
int[] selected = sharedFilesTable.getSelectedRows()
|
||||
if (selected.length == 0)
|
||||
return null
|
||||
List<SharedFile> rv = new ArrayList<>()
|
||||
if (lastSharedSortEvent != null) {
|
||||
for (int i = 0; i < selected.length; i ++) {
|
||||
selected[i] = sharedFilesTable.rowSorter.convertRowIndexToModel(selected[i])
|
||||
if (!settings.sharedFilesAsTree) {
|
||||
def sharedFilesTable = builder.getVariable("shared-files-table")
|
||||
int[] selected = sharedFilesTable.getSelectedRows()
|
||||
if (selected.length == 0)
|
||||
return null
|
||||
List<SharedFile> rv = new ArrayList<>()
|
||||
if (lastSharedSortEvent != null) {
|
||||
for (int i = 0; i < selected.length; i ++) {
|
||||
selected[i] = sharedFilesTable.rowSorter.convertRowIndexToModel(selected[i])
|
||||
}
|
||||
}
|
||||
selected.each {
|
||||
rv.add(model.shared[it])
|
||||
}
|
||||
return rv
|
||||
} else {
|
||||
def sharedFilesTree = builder.getVariable("shared-files-tree")
|
||||
List<SharedFile> rv = new ArrayList<>()
|
||||
for (TreePath path : sharedFilesTree.getSelectionPaths()) {
|
||||
getLeafs(path.getLastPathComponent(), rv)
|
||||
}
|
||||
return rv
|
||||
}
|
||||
selected.each {
|
||||
rv.add(model.shared[it])
|
||||
}
|
||||
|
||||
private static void getLeafs(TreeNode node, List<SharedFile> dest) {
|
||||
if (node.isLeaf()) {
|
||||
dest.add(node.getUserObject())
|
||||
return
|
||||
}
|
||||
def children = node.children()
|
||||
while(children.hasMoreElements()) {
|
||||
getLeafs(children.nextElement(), dest)
|
||||
}
|
||||
rv
|
||||
}
|
||||
|
||||
def copyHashToClipboard() {
|
||||
@@ -876,4 +923,12 @@ class MainFrameView {
|
||||
selectedRow = table.rowSorter.convertRowIndexToModel(selectedRow)
|
||||
selectedRow
|
||||
}
|
||||
|
||||
public void refreshSharedFiles() {
|
||||
if (settings.sharedFilesAsTree) {
|
||||
model.sharedTree.nodeStructureChanged(model.treeRoot)
|
||||
} else {
|
||||
builder.getVariable("shared-files-table").model.fireTableDataChanged()
|
||||
}
|
||||
}
|
||||
}
|
@@ -126,6 +126,12 @@ class OptionsView {
|
||||
excludeLocalResultCheckbox = checkBox(selected : bind {model.excludeLocalResult}, constraints : gbc(gridx: 1, gridy : 6))
|
||||
// label(text : "Show Hash Searches In Monitor", constraints: gbc(gridx:0, gridy:7))
|
||||
// showSearchHashesCheckbox = checkBox(selected : bind {model.showSearchHashes}, constraints : gbc(gridx: 1, gridy: 7))
|
||||
label(text : "Show Shared Files as", constraints: gbc(gridx: 0, gridy:8))
|
||||
panel( constraints : gbc(gridx: 1, gridy: 8)) {
|
||||
buttonGroup(id : "viewShared")
|
||||
radioButton(text: "Tree", selected : bind {model.sharedFilesAsTree}, buttonGroup: viewShared, sharedTreeAction)
|
||||
radioButton(text: "Table", selected : bind {!model.sharedFilesAsTree}, buttonGroup: viewShared, sharedTableAction)
|
||||
}
|
||||
}
|
||||
bandwidth = builder.panel {
|
||||
gridBagLayout()
|
||||
|
Reference in New Issue
Block a user