sort library tree alphabetically

dbus-notify
Zlatin Balevsky 2022-06-24 14:22:23 +01:00
parent c0feafbc08
commit 8802e70226
No known key found for this signature in database
GPG Key ID: A72832072D525E41
5 changed files with 185 additions and 106 deletions

View File

@ -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) {

View File

@ -12,6 +12,11 @@ class InterimTreeNode {
return file;
}
public int hashCode() {
file.hashCode()
}
public boolean equals(Object o) {
if (!(o instanceof InterimTreeNode))
return false

View File

@ -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()
}
}
}

View File

@ -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())
}
}
}

View File

@ -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())
}
}