* fix permission granting logic (when permission are required for both source and destination files)
This commit is contained in:
parent
bf5d7141e0
commit
3c0d44695a
|
@ -38,6 +38,7 @@ import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
|
|
||||||
import net.filebot.ResourceManager;
|
import net.filebot.ResourceManager;
|
||||||
|
import net.filebot.media.MediaDetection;
|
||||||
import net.filebot.ui.HeaderPanel;
|
import net.filebot.ui.HeaderPanel;
|
||||||
import net.filebot.ui.transfer.DefaultTransferHandler;
|
import net.filebot.ui.transfer.DefaultTransferHandler;
|
||||||
import net.filebot.ui.transfer.FileTransferable;
|
import net.filebot.ui.transfer.FileTransferable;
|
||||||
|
@ -46,13 +47,34 @@ import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
public class DropToUnlock extends JList<File> {
|
public class DropToUnlock extends JList<File> {
|
||||||
|
|
||||||
public static boolean showUnlockDialog(Window owner, Collection<File> folders) {
|
public static List<File> getParentFolders(Collection<File> files) {
|
||||||
final List<File> model = folders.stream().map(f -> new File(f.getAbsolutePath())).filter(f -> f.isDirectory()).sorted().distinct().collect(Collectors.toList());
|
return files.stream().map(f -> f.isDirectory() ? f : f.getParentFile()).sorted().distinct().filter(f -> !f.exists() || isLockedFolder(f)).map(f -> {
|
||||||
|
try {
|
||||||
|
File file = f.getCanonicalFile();
|
||||||
|
File root = MediaDetection.getStructureRoot(file);
|
||||||
|
|
||||||
|
// if structure root doesn't work just grab first existing parent folder
|
||||||
|
if (root == null || root.getParentFile() == null || root.getName().isEmpty()) {
|
||||||
|
for (File it : listPathTail(file, Integer.MAX_VALUE, true)) {
|
||||||
|
if (it.isDirectory()) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).filter(f -> f != null && isLockedFolder(f)).sorted().distinct().collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean showUnlockDialog(Window owner, Collection<File> files) {
|
||||||
|
final List<File> model = getParentFolders(files);
|
||||||
|
|
||||||
// TODO store secure bookmarks and auto-unlock folders if possible
|
// TODO store secure bookmarks and auto-unlock folders if possible
|
||||||
|
|
||||||
// check if we even need to unlock anything
|
// check if we even need to unlock anything
|
||||||
if (model.stream().allMatch(f -> !isFolderLocked(f)))
|
if (model.isEmpty() || model.stream().allMatch(f -> !isLockedFolder(f)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
final JDialog dialog = new JDialog(owner);
|
final JDialog dialog = new JDialog(owner);
|
||||||
|
@ -65,13 +87,13 @@ public class DropToUnlock extends JList<File> {
|
||||||
|
|
||||||
// UI feedback for unlocked folders
|
// UI feedback for unlocked folders
|
||||||
for (File it : folders) {
|
for (File it : folders) {
|
||||||
if (!isFolderLocked(it)) {
|
if (!isLockedFolder(it)) {
|
||||||
UILogger.log(Level.INFO, "Folder " + it.getName() + " has been unlocked");
|
UILogger.log(Level.INFO, "Folder " + it.getName() + " has been unlocked");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all folders have been unlocked auto-close dialog
|
// if all folders have been unlocked auto-close dialog
|
||||||
if (model.stream().allMatch(f -> !isFolderLocked(f))) {
|
if (model.stream().allMatch(f -> !isLockedFolder(f))) {
|
||||||
dialogCancelled.set(false);
|
dialogCancelled.set(false);
|
||||||
dialog.setVisible(false);
|
dialog.setVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +215,7 @@ public class DropToUnlock extends JList<File> {
|
||||||
File folder = (File) value;
|
File folder = (File) value;
|
||||||
JLabel c = (JLabel) super.getListCellRendererComponent(list, folder.getName(), index, false, false);
|
JLabel c = (JLabel) super.getListCellRendererComponent(list, folder.getName(), index, false, false);
|
||||||
|
|
||||||
c.setIcon(ResourceManager.getIcon(isFolderLocked(folder) ? "folder.locked" : "folder.open"));
|
c.setIcon(ResourceManager.getIcon(isLockedFolder(folder) ? "folder.locked" : "folder.open"));
|
||||||
c.setHorizontalTextPosition(JLabel.CENTER);
|
c.setHorizontalTextPosition(JLabel.CENTER);
|
||||||
c.setVerticalTextPosition(JLabel.BOTTOM);
|
c.setVerticalTextPosition(JLabel.BOTTOM);
|
||||||
|
|
||||||
|
@ -209,7 +231,7 @@ public class DropToUnlock extends JList<File> {
|
||||||
int index = list.locationToIndex(evt.getPoint());
|
int index = list.locationToIndex(evt.getPoint());
|
||||||
if (index >= 0 && list.getCellBounds(index, index).contains(evt.getPoint())) {
|
if (index >= 0 && list.getCellBounds(index, index).contains(evt.getPoint())) {
|
||||||
File folder = list.getModel().getElementAt(index);
|
File folder = list.getModel().getElementAt(index);
|
||||||
if (isFolderLocked(folder)) {
|
if (isLockedFolder(folder)) {
|
||||||
if (null != showOpenDialogSelectFolder(folder, "Grant Permission", getWindow(list))) {
|
if (null != showOpenDialogSelectFolder(folder, "Grant Permission", getWindow(list))) {
|
||||||
list.updateLockStatus(folder);
|
list.updateLockStatus(folder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class MacAppUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFolderLocked(File folder) {
|
public static boolean isLockedFolder(File folder) {
|
||||||
return folder.isDirectory() && !folder.canRead() && !folder.canWrite();
|
return folder.isDirectory() && !folder.canRead() && !folder.canWrite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import static java.util.Arrays.*;
|
||||||
import static java.util.Collections.*;
|
import static java.util.Collections.*;
|
||||||
import static java.util.regex.Pattern.*;
|
import static java.util.regex.Pattern.*;
|
||||||
import static javax.swing.JOptionPane.*;
|
import static javax.swing.JOptionPane.*;
|
||||||
|
import static net.filebot.Settings.*;
|
||||||
import static net.filebot.UserFiles.*;
|
import static net.filebot.UserFiles.*;
|
||||||
import static net.filebot.util.FileUtilities.*;
|
import static net.filebot.util.FileUtilities.*;
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
@ -69,6 +72,7 @@ import net.filebot.History.Element;
|
||||||
import net.filebot.History.Sequence;
|
import net.filebot.History.Sequence;
|
||||||
import net.filebot.ResourceManager;
|
import net.filebot.ResourceManager;
|
||||||
import net.filebot.Settings;
|
import net.filebot.Settings;
|
||||||
|
import net.filebot.mac.DropToUnlock;
|
||||||
import net.filebot.media.MetaAttributes;
|
import net.filebot.media.MetaAttributes;
|
||||||
import net.filebot.ui.transfer.FileExportHandler;
|
import net.filebot.ui.transfer.FileExportHandler;
|
||||||
import net.filebot.ui.transfer.FileTransferablePolicy;
|
import net.filebot.ui.transfer.FileTransferablePolicy;
|
||||||
|
@ -527,9 +531,15 @@ class HistoryDialog extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rename(File directory, List<Element> elements) {
|
private void rename(File directory, List<Element> elements) {
|
||||||
int count = 0;
|
Map<File, File> renamePlan = getRenameMap(directory);
|
||||||
|
if (isMacSandbox()) {
|
||||||
|
if (!DropToUnlock.showUnlockDialog(parent(), Stream.of(renamePlan.keySet(), renamePlan.values()).flatMap(c -> c.stream()).collect(Collectors.toList()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Entry<File, File> entry : getRenameMap(directory).entrySet()) {
|
int count = 0;
|
||||||
|
for (Entry<File, File> entry : renamePlan.entrySet()) {
|
||||||
try {
|
try {
|
||||||
File destination = moveRename(entry.getKey(), entry.getValue());
|
File destination = moveRename(entry.getKey(), entry.getValue());
|
||||||
count++;
|
count++;
|
||||||
|
@ -544,7 +554,6 @@ class HistoryDialog extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
JLabel status = parent().getInfoLabel();
|
JLabel status = parent().getInfoLabel();
|
||||||
|
|
||||||
if (count == elements.size()) {
|
if (count == elements.size()) {
|
||||||
status.setText(String.format("%d file(s) have been renamed.", count));
|
status.setText(String.format("%d file(s) have been renamed.", count));
|
||||||
status.setIcon(ResourceManager.getIcon("status.ok"));
|
status.setIcon(ResourceManager.getIcon("status.ok"));
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
@ -33,6 +32,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
|
@ -154,15 +155,7 @@ class RenameAction extends AbstractAction {
|
||||||
private Map<File, File> checkRenamePlan(List<Entry<File, File>> renamePlan, Window parent) throws IOException {
|
private Map<File, File> checkRenamePlan(List<Entry<File, File>> renamePlan, Window parent) throws IOException {
|
||||||
// ask for user permissions to output paths
|
// ask for user permissions to output paths
|
||||||
if (isMacSandbox()) {
|
if (isMacSandbox()) {
|
||||||
Set<File> folders = new TreeSet<File>();
|
if (!DropToUnlock.showUnlockDialog(parent, renamePlan.stream().flatMap(e -> Stream.of(e.getValue(), e.getKey())).map(f -> new File(f.getAbsolutePath())).collect(Collectors.toList()))) {
|
||||||
for (Entry<File, File> it : renamePlan) {
|
|
||||||
File structureRoot = MediaDetection.getStructureRoot(it.getValue());
|
|
||||||
if (structureRoot != null) {
|
|
||||||
folders.add(structureRoot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DropToUnlock.showUnlockDialog(parent, folders)) {
|
|
||||||
return emptyMap();
|
return emptyMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue