wip on faster unsharing

dbus-notify
Zlatin Balevsky 2022-08-15 15:28:56 +01:00
parent bad697a8a2
commit 6ff25d32f5
No known key found for this signature in database
GPG Key ID: A72832072D525E41
5 changed files with 137 additions and 63 deletions

View File

@ -6,4 +6,8 @@ import com.muwire.core.SharedFile
class FileUnsharedEvent extends Event {
SharedFile[] unsharedFiles
boolean deleted
/**
* true if the files are implicitly removed as part of unsharing a folder.
*/
boolean implicit
}

View File

@ -580,49 +580,75 @@ class MainFrameController {
}
void unshareSelectedFile() {
def sfs = view.selectedSharedFiles()
/*
* A selection may include files, folders or both.
*/
Set<File> folders = view.selectedFolders()
if (sfs == null && folders.isEmpty())
return
if (sfs == null)
sfs = Collections.emptyList()
List<SharedFile> leafFiles = view.selectedIndividualSharedFiles()
if (leafFiles == null)
leafFiles = Collections.emptyList()
List<SharedFile> toUnshare = new ArrayList<>()
sfs.each { SharedFile sf ->
if (view.settings.collectionWarning) {
Set<InfoHash> collectionsInfoHashes = core.collectionManager.collectionsForFile(sf.rootInfoHash)
if (!collectionsInfoHashes.isEmpty()) {
String[] affected = collectionsInfoHashes.collect({core.collectionManager.getByInfoHash(it)}).collect{it.name}.toArray(new String[0])
if (folders.isEmpty() && leafFiles.isEmpty())
return
boolean [] answer = new boolean[1]
def props = [:]
props.collections = affected
props.answer = answer
props.fileName = sf.file.getName()
props.settings = view.settings
props.home = core.home
def mvc = mvcGroup.createMVCGroup("collection-warning", props)
mvc.destroy()
if (!answer[0]) {
File f = sf.getFile()
while(true) {
File parent = f.getParentFile()
if (parent == null)
break
folders.remove(parent)
f = parent
}
return
}
}
List<SharedFile> implicitUnshared = new ArrayList<>()
for (File folder : folders) {
List<SharedFile> contained = model.sharedTree.getFilesInFolder(folder)
for (SharedFile sf : contained) {
if (collectionMembershipCheck(sf))
implicitUnshared.add sf
else
return
}
toUnshare.add(sf)
}
if (!folders.isEmpty())
List<SharedFile> explicitUnshared = new ArrayList<>()
for (SharedFile sf : leafFiles) {
if (collectionMembershipCheck(sf))
explicitUnshared << sf
else
return
}
if (!folders.isEmpty()) {
for (File folder : folders) {
model.sharedTree.removeFromTree(folder)
model.allFilesSharedTree.removeFromTree(folder)
}
core.eventBus.publish(new DirectoryUnsharedEvent(directories: folders.toArray(new File[0]), deleted: false))
if (!toUnshare.isEmpty())
core.eventBus.publish(new FileUnsharedEvent(unsharedFiles : toUnshare.toArray(new SharedFile[0])))
core.eventBus.publish(new FileUnsharedEvent(
unsharedFiles: implicitUnshared.toArray(new SharedFile[0]),
deleted: false,
implicit: true
))
}
if (!explicitUnshared.isEmpty())
core.eventBus.publish(new FileUnsharedEvent(unsharedFiles : explicitUnshared.toArray(new SharedFile[0])))
}
/**
* @param sharedFile that may be in a collection
* @return true if the file should be unshared
*/
private boolean collectionMembershipCheck(SharedFile sf) {
if (!view.settings.collectionWarning)
return true
Set<InfoHash> collectionsInfoHashes = core.collectionManager.collectionsForFile(sf.rootInfoHash)
if (!collectionsInfoHashes.isEmpty()) {
String[] affected = collectionsInfoHashes.collect({core.collectionManager.getByInfoHash(it)}).collect{it.name}.toArray(new String[0])
boolean [] answer = new boolean[1]
def props = [:]
props.collections = affected
props.answer = answer
props.fileName = sf.file.getName()
props.settings = view.settings
props.home = core.home
def mvc = mvcGroup.createMVCGroup("collection-warning", props)
mvc.destroy()
return answer[0]
}
return true
}
@ControllerAction

View File

@ -621,21 +621,19 @@ class MainFrameModel {
loadedFiles = allSharedFiles.size()
for (SharedFile sharedFile : e.unsharedFiles) {
removeUnsharedFromTree(sharedFile, e.deleted)
if (fileToNode.remove(sharedFile) == null)
continue
if (e.implicit)
continue
allFilesSharedTree.removeFromTree(sharedFile, e.deleted)
sharedTree.removeFromTree(sharedFile, e.deleted)
}
view.refreshSharedFiles()
}
}
private void removeUnsharedFromTree(SharedFile sharedFile, boolean deleted) {
SortedTreeNode dmtn = fileToNode.remove(sharedFile)
if (dmtn == null)
return
allFilesSharedTree.removeFromTree(sharedFile, deleted)
sharedTree.removeFromTree(sharedFile, deleted)
}
void onUploadEvent(UploadEvent e) {
runInsideUIAsync {
int index = -1

View File

@ -1533,6 +1533,23 @@ class MainFrameView {
return rv
}
}
List<SharedFile> selectedIndividualSharedFiles() {
if (!model.treeVisible)
return selectedSharedFiles()
else {
List<SharedFile> rv = new ArrayList<>()
def sharedFilesTree = builder.getVariable("shared-files-tree")
TreePath[] selectedPaths = sharedFilesTree.getSelectionPaths()
for (TreePath path : selectedPaths) {
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent()
Object obj = dmtn.getUserObject()
if (obj instanceof SharedFile)
rv << obj
}
return rv
}
}
/**
* @return if a single file is selected, return it.

View File

@ -14,7 +14,7 @@ class LibraryTreeModel extends DefaultTreeModel {
}
TreeNode addToTree(SharedFile sharedFile) {
List<File> parents = getParents(sharedFile)
List<File> parents = getParents(sharedFile.getFile())
LibraryTreeNode node = root
for (File path : parents) {
def key = new InterimTreeNode(path)
@ -32,21 +32,33 @@ class LibraryTreeModel extends DefaultTreeModel {
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
void removeFromTree(File folder) {
def node = findParentNode(folder, false)
def key = new InterimTreeNode(folder)
def child = node.getByKey(key)
while(true) {
def parent = child.getParent()
child.removeFromParent()
if (parent.getChildCount() == 0 && parent != root)
child = parent
else
break
}
}
List<SharedFile> getFilesInFolder(File folder) {
def node = findParentNode(folder, false)
def key = new InterimTreeNode(folder)
def child = node.getByKey(key)
List<SharedFile> rv = []
TreeUtil.getLeafs(child, rv)
rv
}
void removeFromTree(SharedFile sharedFile, boolean deleted) {
def node = findParentNode(sharedFile.getFile(), deleted)
def leaf = node.getByKey(sharedFile)
while(true) {
def parent = leaf.getParent()
leaf.removeFromParent()
@ -57,9 +69,26 @@ class LibraryTreeModel extends DefaultTreeModel {
}
}
private List<File> getParents(SharedFile sharedFile) {
private LibraryTreeNode findParentNode(File file, boolean deleted) {
List<File> parents = getParents(file)
LibraryTreeNode node = root
for (File path : parents) {
def key = new InterimTreeNode(path)
def child = node.getByKey(key)
if (child == null) {
if (deleted)
return null
throw new IllegalStateException()
}
node = child
}
node
}
private static List<File> getParents(File sharedFile) {
List<File> parents = new ArrayList<>()
File tmp = sharedFile.file.getParentFile()
File tmp = sharedFile.getParentFile()
while(tmp.getParent() != null) {
parents << tmp
tmp = tmp.getParentFile()