* improved support for move/rename

This commit is contained in:
Reinhard Pointner 2009-10-29 01:22:00 +00:00
parent 0a2d323ac4
commit f61b084769
6 changed files with 125 additions and 29 deletions

View File

@ -49,7 +49,6 @@ class ExpressionFormatDocument extends PlainDocument {
RoundBrackets("()"),
SquareBrackets("[]"),
CurlyBrackets("{}"),
RegexLiteral("//"),
SingleQuoteStringLiteral("''"),
DoubleQuoteStringLiteral("\"\"");

View File

@ -25,12 +25,12 @@ import net.sourceforge.tuned.ui.TunedUtilities;
class HighlightListCellRenderer extends AbstractFancyListCellRenderer {
private final JTextComponent textComponent = new JTextField();
private Pattern pattern;
private Highlighter.HighlightPainter highlightPainter;
protected final JTextComponent textComponent = new JTextField();
protected final Pattern pattern;
protected final Highlighter.HighlightPainter highlightPainter;
public HighlightListCellRenderer(Pattern pattern, Highlighter.HighlightPainter highlightPainter, int padding) {
super(new Insets(0, 0, 0, 0));
@ -84,7 +84,7 @@ class HighlightListCellRenderer extends AbstractFancyListCellRenderer {
}
}
private class HighlightUpdateListener implements DocumentListener {
@Override

View File

@ -531,8 +531,14 @@ class HistoryDialog extends JDialog {
File dir = directory != null ? directory : element.dir();
// reverse
File from = new File(dir, element.to());
File to = new File(dir, element.from());
File from = new File(element.to());
File to = new File(element.from());
// resolve against given directory or against the original base directory if the path is not absolute
if (!from.isAbsolute())
from = new File(dir, directory == null ? from.getPath() : from.getName());
if (!to.isAbsolute())
to = new File(dir, directory == null ? to.getPath() : to.getName());
renameMap.put(from, to);
}
@ -847,7 +853,12 @@ class HistoryDialog extends JDialog {
public boolean isBroken(int row) {
Element element = data.get(row);
File file = new File(element.dir(), element.to());
File file = new File(element.to());
// resolve relative path
if (!file.isAbsolute())
file = new File(element.dir(), file.getPath());
return !file.exists();
}

View File

@ -91,10 +91,15 @@ class RenameAction extends AbstractAction {
private File rename(File file, String path) throws IOException {
// same folder, different name
File destination = new File(file.getParentFile(), path);
File destination = new File(path);
// name may be a relative path, so we can't use file.getParentFile()
// resolve destination
if (!destination.isAbsolute()) {
// same folder, different name
destination = new File(file.getParentFile(), path);
}
// make sure we that we can create the destination folder structure
File destinationFolder = destination.getParentFile();
// create parent folder if necessary

View File

@ -10,11 +10,15 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import javax.swing.AbstractAction;
import javax.swing.Action;
@ -25,6 +29,7 @@ import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import net.miginfocom.swing.MigLayout;
import net.sourceforge.filebot.ResourceManager;
@ -47,13 +52,37 @@ class ValidateDialog extends JDialog {
list = new JList(model);
list.setEnabled(false);
list.setCellRenderer(new HighlightListCellRenderer(ILLEGAL_CHARACTERS, new CharacterHighlightPainter(new Color(0xFF4200), new Color(0xFF1200)), 4));
list.setCellRenderer(new HighlightListCellRenderer(ILLEGAL_CHARACTERS, new CharacterHighlightPainter(new Color(0xFF4200), new Color(0xFF1200)), 4) {
@Override
protected void updateHighlighter() {
textComponent.getHighlighter().removeAllHighlights();
Matcher matcher = pattern.matcher(textComponent.getText());
File file = new File(textComponent.getText());
// highlight path components separately to ignore "illegal characters" that are either path separators or part of the drive letter (e.g. ':' in 'E:')
for (File element : listPath(file)) {
int limit = element.getPath().length();
matcher.region(limit - element.getName().length(), limit);
while (matcher.find()) {
try {
textComponent.getHighlighter().addHighlight(matcher.start(0), matcher.end(0), highlightPainter);
} catch (BadLocationException e) {
//should not happen
Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.toString(), e);
}
}
}
}
});
JLabel label = new JLabel("Some names contain invalid characters:");
JComponent content = (JComponent) getContentPane();
content.setLayout(new MigLayout("insets dialog, nogrid, fill"));
content.setLayout(new MigLayout("insets dialog, nogrid, fill", "", "[pref!][fill][pref!]"));
content.add(label, "wrap");
content.add(new JScrollPane(list), "grow, wrap 2mm");
@ -94,7 +123,8 @@ class ValidateDialog extends JDialog {
public void actionPerformed(ActionEvent e) {
// validate names
for (int i = 0; i < model.length; i++) {
model[i] = validateFileName(model[i]);
// remove illegal characters
model[i] = validateFilePath(new File(model[i])).getPath();
}
// update view
@ -126,22 +156,23 @@ class ValidateDialog extends JDialog {
public static boolean validate(Component parent, List<String> source) {
IndexView<String> invalid = new IndexView<String>(source);
IndexView<String> invalidFilePaths = new IndexView<String>(source);
for (int i = 0; i < source.size(); i++) {
String name = source.get(i);
String path = source.get(i);
if (isInvalidFileName(name)) {
invalid.addIndex(i);
// invalid file names are also invalid file paths
if (isInvalidFilePath(new File(path))) {
invalidFilePaths.addIndex(i);
}
}
if (invalid.isEmpty()) {
// nothing to do
// check if there is anything to do in the first place
if (invalidFilePaths.isEmpty()) {
return true;
}
ValidateDialog dialog = new ValidateDialog(getWindow(parent), invalid);
ValidateDialog dialog = new ValidateDialog(getWindow(parent), invalidFilePaths);
// show and block
dialog.setVisible(true);
@ -151,11 +182,11 @@ class ValidateDialog extends JDialog {
return false;
}
List<String> valid = dialog.getModel();
List<String> validatedFilePaths = dialog.getModel();
// validate source list via index view
for (int i = 0; i < invalid.size(); i++) {
invalid.set(i, valid.get(i));
for (int i = 0; i < invalidFilePaths.size(); i++) {
invalidFilePaths.set(i, validatedFilePaths.get(i));
}
return true;

View File

@ -9,6 +9,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -140,6 +142,17 @@ public final class FileUtilities {
}
public static List<File> listPath(File file) {
LinkedList<File> nodes = new LinkedList<File>();
for (File node = file; node != null; node = node.getParentFile()) {
nodes.addFirst(node);
}
return nodes;
}
public static List<File> listFiles(Iterable<File> folders, int maxDepth) {
List<File> files = new ArrayList<File>();
@ -167,28 +180,65 @@ public final class FileUtilities {
/**
* Invalid filename characters: \, /, :, *, ?, ", <, >, |, \r and \n
* Invalid file name characters: \, /, :, *, ?, ", <, >, |, \r and \n
*/
public static final Pattern ILLEGAL_CHARACTERS = Pattern.compile("[\\\\/:*?\"<>|\\r\\n]");
/**
* Strip filename of invalid characters
* Strip file name of invalid characters
*
* @param filename original filename
* @return valid filename stripped of invalid characters
* @return valid file name stripped of invalid characters
*/
public static String validateFileName(CharSequence filename) {
// strip invalid characters from filename
// strip invalid characters from file name
return ILLEGAL_CHARACTERS.matcher(filename).replaceAll("");
}
public static boolean isInvalidFileName(CharSequence filename) {
// check if file name contains any illegal characters
return ILLEGAL_CHARACTERS.matcher(filename).find();
}
public static File validateFileName(File file) {
// windows drives (e.g. c:, d:, etc.) are never invalid because name will be an empty string
if (!isInvalidFileName(file.getName()))
return file;
// validate file name only
return new File(file.getParentFile(), validateFileName(file.getName()));
}
public static File validateFilePath(File path) {
Iterator<File> nodes = listPath(path).iterator();
// initialize with root node, keep original root object if possible (so we don't loose the drive on windows)
File validatedPath = validateFileName(nodes.next());
// validate the rest of the path
while (nodes.hasNext()) {
validatedPath = new File(validatedPath, validateFileName(nodes.next().getName()));
}
return validatedPath;
}
public static boolean isInvalidFilePath(File path) {
// check if file name contains any illegal characters
for (File node = path; node != null; node = node.getParentFile()) {
if (isInvalidFileName(node.getName()))
return true;
}
return false;
}
public static final long KILO = 1024;
public static final long MEGA = KILO * 1024;
public static final long GIGA = MEGA * 1024;