mirror of https://github.com/zlatinb/muwire
sort library tree alphabetically
parent
c0feafbc08
commit
8802e70226
|
@ -130,8 +130,8 @@ class MainFrameModel {
|
|||
private boolean libraryDirty
|
||||
boolean libraryTabVisible
|
||||
private final javax.swing.Timer libraryTimer = new javax.swing.Timer(1000, {refreshLibrary()})
|
||||
TreeModel sharedTree
|
||||
DefaultMutableTreeNode allFilesTreeRoot, treeRoot
|
||||
LibraryTreeModel allFilesSharedTree, sharedTree
|
||||
SortedTreeNode<SharedFile> allFilesTreeRoot, treeRoot
|
||||
final Map<SharedFile, TreeNode> fileToNode = new HashMap<>()
|
||||
|
||||
def connectionList = []
|
||||
|
@ -247,9 +247,10 @@ class MainFrameModel {
|
|||
(Image) view.builder.imageIcon("/email.png").image)
|
||||
|
||||
shared = []
|
||||
treeRoot = new DefaultMutableTreeNode()
|
||||
sharedTree = new DefaultTreeModel(treeRoot)
|
||||
allFilesTreeRoot = new DefaultMutableTreeNode()
|
||||
treeRoot = new LibraryTreeModel.LibraryTreeNode()
|
||||
sharedTree = new LibraryTreeModel(treeRoot)
|
||||
allFilesTreeRoot = new LibraryTreeModel.LibraryTreeNode()
|
||||
allFilesSharedTree = new LibraryTreeModel(allFilesTreeRoot)
|
||||
|
||||
Timer timer = new Timer("download-pumper", true)
|
||||
timer.schedule({
|
||||
|
@ -497,10 +498,10 @@ class MainFrameModel {
|
|||
if (e.duplicate != null)
|
||||
allSharedFiles.remove(e.duplicate)
|
||||
allSharedFiles << e.sharedFile
|
||||
insertIntoTree(e.sharedFile, allFilesTreeRoot, fileToNode)
|
||||
insertIntoTree(e.sharedFile, allFilesSharedTree, fileToNode)
|
||||
if (filter(e.sharedFile)) {
|
||||
insertIntoTable(e.sharedFile)
|
||||
insertIntoTree(e.sharedFile, treeRoot, null)
|
||||
insertIntoTree(e.sharedFile, sharedTree, null)
|
||||
libraryDirty = true
|
||||
}
|
||||
}
|
||||
|
@ -511,9 +512,9 @@ class MainFrameModel {
|
|||
return
|
||||
runInsideUIAsync {
|
||||
allSharedFiles << e.loadedFile
|
||||
insertIntoTree(e.loadedFile, allFilesTreeRoot, fileToNode)
|
||||
insertIntoTree(e.loadedFile, allFilesSharedTree, fileToNode)
|
||||
insertIntoTable(e.loadedFile)
|
||||
insertIntoTree(e.loadedFile, treeRoot, null)
|
||||
insertIntoTree(e.loadedFile, sharedTree, null)
|
||||
libraryDirty = true
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +548,7 @@ class MainFrameModel {
|
|||
insertIntoTable(sf)
|
||||
}
|
||||
shared.each {
|
||||
insertIntoTree(it, treeRoot, null)
|
||||
insertIntoTree(it, sharedTree, null)
|
||||
}
|
||||
view.refreshSharedFiles()
|
||||
view.magicTreeExpansion()
|
||||
|
@ -577,7 +578,7 @@ class MainFrameModel {
|
|||
for (SharedFile sf : chunks)
|
||||
insertIntoTable(sf)
|
||||
chunks.each {
|
||||
insertIntoTree(it, treeRoot, null)
|
||||
insertIntoTree(it, sharedTree, null)
|
||||
}
|
||||
view.refreshSharedFiles()
|
||||
}
|
||||
|
@ -616,36 +617,12 @@ class MainFrameModel {
|
|||
}
|
||||
|
||||
private void removeUnsharedFromTree(SharedFile sharedFile, boolean deleted) {
|
||||
DefaultMutableTreeNode dmtn = fileToNode.remove(sharedFile)
|
||||
SortedTreeNode dmtn = fileToNode.remove(sharedFile)
|
||||
if (dmtn == null)
|
||||
return
|
||||
|
||||
Object[] path = dmtn.getUserObjectPath()
|
||||
DefaultMutableTreeNode otherNode = treeRoot
|
||||
for (int i = 1; i < path.length; i++) {
|
||||
Object o = path[i]
|
||||
DefaultMutableTreeNode next = null
|
||||
for (int j = 0; j < otherNode.childCount; j++) {
|
||||
if (otherNode.getChildAt(j).getUserObject() == o) {
|
||||
next = otherNode.getChildAt(j)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (next == null) {
|
||||
if (deleted)
|
||||
return
|
||||
throw new IllegalStateException()
|
||||
}
|
||||
otherNode = next
|
||||
}
|
||||
while (true) {
|
||||
def parent = otherNode.getParent()
|
||||
otherNode.removeFromParent()
|
||||
if (parent.getChildCount() == 0) {
|
||||
otherNode = parent
|
||||
} else
|
||||
break
|
||||
}
|
||||
allFilesSharedTree.removeFromTree(sharedFile, deleted)
|
||||
sharedTree.removeFromTree(sharedFile, deleted)
|
||||
}
|
||||
|
||||
void onUploadEvent(UploadEvent e) {
|
||||
|
@ -845,10 +822,10 @@ class MainFrameModel {
|
|||
return
|
||||
runInsideUIAsync {
|
||||
allSharedFiles << e.downloadedFile
|
||||
insertIntoTree(e.downloadedFile, allFilesTreeRoot, fileToNode)
|
||||
insertIntoTree(e.downloadedFile, allFilesSharedTree, fileToNode)
|
||||
if (filter(e.downloadedFile)) {
|
||||
insertIntoTable(e.downloadedFile)
|
||||
insertIntoTree(e.downloadedFile,treeRoot, null)
|
||||
insertIntoTree(e.downloadedFile,sharedTree, null)
|
||||
libraryDirty = true
|
||||
}
|
||||
}
|
||||
|
@ -866,37 +843,9 @@ class MainFrameModel {
|
|||
}
|
||||
}
|
||||
|
||||
private void insertIntoTree(SharedFile file, TreeNode root, Map<File,TreeNode> f2n) {
|
||||
List<File> parents = new ArrayList<>()
|
||||
File tmp = file.file.getParentFile()
|
||||
while(tmp.getParent() != null) {
|
||||
parents << tmp
|
||||
tmp = tmp.getParentFile()
|
||||
}
|
||||
Collections.reverse(parents)
|
||||
TreeNode node = root
|
||||
for(File path : parents) {
|
||||
boolean exists = false
|
||||
def children = node.children()
|
||||
def child = null
|
||||
while(children.hasMoreElements()) {
|
||||
child = children.nextElement()
|
||||
def userObject = child.getUserObject()
|
||||
if (userObject != null && userObject.file == path) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!exists) {
|
||||
child = new DefaultMutableTreeNode(new InterimTreeNode(path))
|
||||
node.add(child)
|
||||
}
|
||||
node = child
|
||||
}
|
||||
|
||||
def dmtn = new DefaultMutableTreeNode(file)
|
||||
f2n?.put(file, dmtn)
|
||||
node.add(dmtn)
|
||||
private void insertIntoTree(SharedFile file, LibraryTreeModel libraryTreeModel, Map<SharedFile,TreeNode> f2n) {
|
||||
def leaf = libraryTreeModel.addToTree(file)
|
||||
f2n?.put(file, leaf)
|
||||
}
|
||||
|
||||
private void insertIntoTable(SharedFile sharedFile) {
|
||||
|
|
|
@ -12,6 +12,11 @@ class InterimTreeNode {
|
|||
return file;
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
file.hashCode()
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof InterimTreeNode))
|
||||
return false
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import com.muwire.core.SharedFile
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
import javax.swing.tree.DefaultTreeModel
|
||||
import javax.swing.tree.TreeNode
|
||||
import java.text.Collator
|
||||
|
||||
class LibraryTreeModel extends DefaultTreeModel {
|
||||
|
||||
LibraryTreeModel(TreeNode root) {
|
||||
super(root)
|
||||
}
|
||||
|
||||
TreeNode addToTree(SharedFile sharedFile) {
|
||||
List<File> parents = getParents(sharedFile)
|
||||
LibraryTreeNode node = root
|
||||
for (File path : parents) {
|
||||
def key = new InterimTreeNode(path)
|
||||
def child = node.getByKey(key)
|
||||
if (child == null) {
|
||||
child = new LibraryTreeNode()
|
||||
child.setUserObject(key)
|
||||
node.addDescendant(child)
|
||||
}
|
||||
node = child
|
||||
}
|
||||
|
||||
def leaf = new LibraryTreeNode(sharedFile)
|
||||
node.addDescendant(leaf)
|
||||
leaf
|
||||
}
|
||||
|
||||
void removeFromTree(SharedFile sharedFile, boolean deleted) {
|
||||
List<File> parents = getParents(sharedFile)
|
||||
LibraryTreeNode node = root
|
||||
|
||||
for (File path : parents) {
|
||||
def key = new InterimTreeNode(path)
|
||||
def child = node.getByKey(key)
|
||||
if (child == null) {
|
||||
if (deleted)
|
||||
return
|
||||
throw new IllegalStateException()
|
||||
}
|
||||
node = child
|
||||
}
|
||||
def leaf = node.getByKey(sharedFile)
|
||||
while(true) {
|
||||
def parent = leaf.getParent()
|
||||
leaf.removeFromParent()
|
||||
if (parent.getChildCount() == 0 && parent != root)
|
||||
leaf = parent
|
||||
else
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private List<File> getParents(SharedFile sharedFile) {
|
||||
List<File> parents = new ArrayList<>()
|
||||
File tmp = sharedFile.file.getParentFile()
|
||||
while(tmp.getParent() != null) {
|
||||
parents << tmp
|
||||
tmp = tmp.getParentFile()
|
||||
}
|
||||
Collections.reverse(parents)
|
||||
parents
|
||||
}
|
||||
|
||||
static class LibraryTreeNode extends SortedTreeNode<SharedFile> {
|
||||
|
||||
LibraryTreeNode() {
|
||||
super()
|
||||
}
|
||||
|
||||
LibraryTreeNode(SharedFile sharedFile) {
|
||||
super(sharedFile)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStringName() {
|
||||
def object = getUserObject()
|
||||
if (object instanceof SharedFile)
|
||||
return object.getFile().getName()
|
||||
else
|
||||
return object.toString()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ class ResultTreeModel extends DefaultTreeModel {
|
|||
MutableResultNode node = root
|
||||
if (event.path == null || event.path.length == 0) {
|
||||
def child = new MutableResultNode(event)
|
||||
node.addResult(child)
|
||||
node.addDescendant(child)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -29,65 +29,37 @@ class ResultTreeModel extends DefaultTreeModel {
|
|||
String hiddenRoot = elements.remove(0)
|
||||
for (String element : elements) {
|
||||
def nodeData = new ResultTreeRenderer.ResultTreeNode(hiddenRoot, element)
|
||||
def elementNode = node.childrenMap.get(nodeData)
|
||||
def elementNode = node.getByKey(nodeData)
|
||||
|
||||
if (elementNode == null) {
|
||||
elementNode = new MutableResultNode()
|
||||
elementNode.setUserObject(nodeData)
|
||||
node.addResult(elementNode)
|
||||
node.addDescendant(elementNode)
|
||||
}
|
||||
elementNode.getUserObject().addResult(event)
|
||||
node = elementNode
|
||||
}
|
||||
|
||||
def fileNode = new MutableResultNode(event)
|
||||
node.addResult(fileNode)
|
||||
node.addDescendant(fileNode)
|
||||
}
|
||||
|
||||
static class MutableResultNode extends DefaultMutableTreeNode implements Comparable<MutableResultNode>{
|
||||
private final Map<Object, MutableResultNode> childrenMap
|
||||
static class MutableResultNode extends SortedTreeNode<UIResultEvent> {
|
||||
MutableResultNode() {
|
||||
super()
|
||||
childrenMap = new HashMap<>()
|
||||
}
|
||||
|
||||
MutableResultNode(UIResultEvent event) {
|
||||
super()
|
||||
childrenMap = Collections.emptyMap()
|
||||
setUserObject(event)
|
||||
super(event)
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeAllChildren() {
|
||||
if (!childrenMap.isEmpty())
|
||||
childrenMap.clear()
|
||||
super.removeAllChildren()
|
||||
}
|
||||
|
||||
void addResult(MutableResultNode newChild) {
|
||||
childrenMap.put(newChild.getUserObject(), newChild)
|
||||
if (children == null)
|
||||
children = new Vector<>()
|
||||
Object [] elementData = children.elementData
|
||||
int idx = Arrays.binarySearch(elementData, 0, getChildCount(), newChild)
|
||||
if (idx >= 0)
|
||||
idx++
|
||||
else
|
||||
idx = - idx - 1
|
||||
insert(newChild, idx)
|
||||
}
|
||||
|
||||
private String getStringName() {
|
||||
protected String getStringName() {
|
||||
def object = getUserObject()
|
||||
if (object instanceof UIResultEvent)
|
||||
return object.getName()
|
||||
else
|
||||
return object.toString()
|
||||
}
|
||||
|
||||
@Override
|
||||
int compareTo(MutableResultNode other) {
|
||||
Collator.getInstance().compare(getStringName(), other.getStringName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
import javax.swing.tree.MutableTreeNode
|
||||
import javax.swing.tree.TreeNode
|
||||
import java.text.Collator
|
||||
|
||||
/**
|
||||
* A tree node that keeps it's children sorted.
|
||||
*/
|
||||
abstract class SortedTreeNode<T> extends DefaultMutableTreeNode implements Comparable<SortedTreeNode> {
|
||||
private final Map<Object, SortedTreeNode> childrenMap
|
||||
|
||||
SortedTreeNode() {
|
||||
super()
|
||||
childrenMap = new HashMap<>()
|
||||
}
|
||||
|
||||
SortedTreeNode(T element) {
|
||||
super()
|
||||
childrenMap = Collections.emptyMap()
|
||||
setUserObject(element)
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeAllChildren() {
|
||||
if (!childrenMap.isEmpty())
|
||||
childrenMap.clear()
|
||||
super.removeAllChildren()
|
||||
}
|
||||
|
||||
@Override
|
||||
void remove(MutableTreeNode aChild) {
|
||||
if (!(aChild instanceof SortedTreeNode))
|
||||
throw new IllegalStateException()
|
||||
childrenMap.remove(aChild.getUserObject())
|
||||
super.remove(aChild)
|
||||
}
|
||||
|
||||
SortedTreeNode getByKey(Object key) {
|
||||
childrenMap[key]
|
||||
}
|
||||
|
||||
void addDescendant(SortedTreeNode<T> newChild) {
|
||||
childrenMap.put(newChild.getUserObject(), newChild)
|
||||
if (children == null)
|
||||
children = new Vector<>()
|
||||
Object [] elementData = children.elementData
|
||||
int idx = Arrays.binarySearch(elementData, 0, getChildCount(), newChild)
|
||||
if (idx >= 0)
|
||||
idx++
|
||||
else
|
||||
idx = - idx - 1
|
||||
insert(newChild, idx)
|
||||
}
|
||||
|
||||
protected abstract String getStringName()
|
||||
|
||||
@Override
|
||||
final int compareTo(SortedTreeNode other) {
|
||||
Collator.getInstance().compare(getStringName(), other.getStringName())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue