* added extra hints for when user input is required for movie/series identification
This commit is contained in:
parent
2cdd0ddc17
commit
02f789e1bf
|
@ -278,16 +278,16 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
|||
String parentPathHint = normalizePathSeparators(getRelativePathTail(files.get(0).getParentFile(), 2).getPath());
|
||||
String suggestion = detectedSeriesNames.size() > 0 ? join(detectedSeriesNames, ", ") : parentPathHint;
|
||||
|
||||
List<String> input = emptyList();
|
||||
List<String> input;
|
||||
synchronized (inputMemory) {
|
||||
input = inputMemory.get(suggestion);
|
||||
if (input == null || suggestion == null || suggestion.isEmpty()) {
|
||||
input = showMultiValueInputDialog("Enter series name:", suggestion, parentPathHint, parent);
|
||||
input = showMultiValueInputDialog(getQueryInputMessage(files), suggestion, parentPathHint, parent);
|
||||
inputMemory.put(suggestion, input);
|
||||
}
|
||||
}
|
||||
|
||||
if (input.size() > 0) {
|
||||
if (input != null && input.size() > 0) {
|
||||
// only allow one fetch session at a time so later requests can make use of cached results
|
||||
synchronized (providerLock) {
|
||||
episodes = fetchEpisodeSet(input, sortOrder, locale, new HashMap<String, SearchResult>(), parent);
|
||||
|
@ -309,14 +309,39 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
|||
return matches;
|
||||
}
|
||||
|
||||
protected String getQueryInputMessage(List<File> files) throws Exception {
|
||||
StringBuilder html = new StringBuilder(512);
|
||||
html.append("<html>");
|
||||
html.append("Unable to identify the following files:").append("<br>");
|
||||
|
||||
for (File file : sortByUniquePath(files)) {
|
||||
html.append("<nobr>");
|
||||
html.append("• ");
|
||||
|
||||
File path = getStructurePathTail(file);
|
||||
if (path == null) {
|
||||
path = getRelativePathTail(file, 3);
|
||||
}
|
||||
|
||||
new TextColorizer().colorizePath(html, path, true);
|
||||
html.append("</nobr>");
|
||||
html.append("<br>");
|
||||
}
|
||||
|
||||
html.append("<br>");
|
||||
html.append("Please enter series name:");
|
||||
html.append("</html>");
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
public List<Match<File, ?>> justFetchEpisodeList(final SortOrder sortOrder, final Locale locale, final Component parent) throws Exception {
|
||||
// require user input
|
||||
String input = showInputDialog("Enter series name:", "", "Fetch Episode List", parent);
|
||||
List<String> input = showMultiValueInputDialog("Enter series name:", "", "Fetch Episode List", parent);
|
||||
|
||||
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
|
||||
if (input != null && input.length() > 0) {
|
||||
if (input.size() > 0) {
|
||||
synchronized (providerLock) {
|
||||
Set<Episode> episodes = fetchEpisodeSet(singleton(input), sortOrder, locale, new HashMap<String, SearchResult>(), parent);
|
||||
Set<Episode> episodes = fetchEpisodeSet(input, sortOrder, locale, new HashMap<String, SearchResult>(), parent);
|
||||
for (Episode it : episodes) {
|
||||
matches.add(new Match<File, Episode>(null, it));
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ class MovieHashMatcher implements AutoCompleteMatcher {
|
|||
String input = inputMemory.get(suggestion);
|
||||
if (input == null || suggestion == null || suggestion.isEmpty()) {
|
||||
File movieFolder = guessMovieFolder(movieFile);
|
||||
input = showInputDialog("Enter movie name:", suggestion != null && suggestion.length() > 0 ? suggestion : getName(movieFile), movieFolder == null ? movieFile.getName() : String.format("%s/%s", movieFolder.getName(), movieFile.getName()), parent);
|
||||
input = showInputDialog(getQueryInputMessage(movieFile), suggestion != null && suggestion.length() > 0 ? suggestion : getName(movieFile), movieFolder == null ? movieFile.getName() : String.format("%s/%s", movieFolder.getName(), movieFile.getName()), parent);
|
||||
inputMemory.put(suggestion, input);
|
||||
}
|
||||
|
||||
|
@ -292,6 +292,28 @@ class MovieHashMatcher implements AutoCompleteMatcher {
|
|||
return options.isEmpty() ? null : selectMovie(movieFile, null, options, memory, parent);
|
||||
}
|
||||
|
||||
protected String getQueryInputMessage(File file) throws Exception {
|
||||
File path = getStructurePathTail(file);
|
||||
if (path == null) {
|
||||
path = getRelativePathTail(file, 3);
|
||||
}
|
||||
|
||||
StringBuilder html = new StringBuilder(512);
|
||||
html.append("<html>");
|
||||
html.append("Unable to identify the following files:").append("<br>");
|
||||
|
||||
html.append("<nobr>");
|
||||
html.append("• ");
|
||||
new TextColorizer().colorizePath(html, path, file.isFile());
|
||||
html.append("</nobr>");
|
||||
html.append("<br>");
|
||||
|
||||
html.append("<br>");
|
||||
html.append("Please enter movie name:");
|
||||
html.append("</html>");
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
protected String checkedStripReleaseInfo(File file) throws Exception {
|
||||
String name = stripReleaseInfo(getName(file));
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.awt.RenderingHints;
|
|||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JList;
|
||||
|
@ -44,8 +43,7 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
|
|||
private Color warningGradientBeginColor = Color.RED;
|
||||
private Color warningGradientEndColor = new Color(0xDC143C);
|
||||
|
||||
private Color pathRainbowBeginColor = new Color(0xCC3300);
|
||||
private Color pathRainbowEndColor = new Color(0x008080);
|
||||
private TextColorizer textColorizer = new TextColorizer();
|
||||
|
||||
public RenameListCellRenderer(RenameModel renameModel) {
|
||||
super(new Insets(4, 7, 4, 7));
|
||||
|
@ -164,29 +162,11 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
|
|||
}
|
||||
|
||||
protected String colorizePath(File file, boolean hasExtension) {
|
||||
List<File> path = listPath(file);
|
||||
StringBuilder html = new StringBuilder(512);
|
||||
html.append("<html><nobr>");
|
||||
|
||||
// colorize parent path
|
||||
for (int i = 0; i < path.size() - 1; i++) {
|
||||
float f = (path.size() <= 2) ? 1 : (float) i / (path.size() - 2);
|
||||
Color c = interpolateHSB(pathRainbowBeginColor, pathRainbowEndColor, f);
|
||||
html.append(String.format("<span style='color:rgb(%1$d, %2$d, %3$d)'>%4$s</span><span style='color:rgb(%1$d, %2$d, %3$d)'>/</span>", c.getRed(), c.getGreen(), c.getBlue(), escapeHTML(FileUtilities.getFolderName(path.get(i)))));
|
||||
}
|
||||
|
||||
// only colorize extension
|
||||
if (hasExtension) {
|
||||
html.append(escapeHTML(FileUtilities.getName(file)));
|
||||
String extension = FileUtilities.getExtension(file);
|
||||
if (extension != null) {
|
||||
html.append(String.format("<span style='color:#607080'>.%s</span>", escapeHTML(extension))); // highlight extension
|
||||
}
|
||||
} else {
|
||||
html.append(file.getName());
|
||||
}
|
||||
|
||||
return html.append("</nobr></html>").toString();
|
||||
textColorizer.colorizePath(html, file, hasExtension);
|
||||
html.append("</nobr></html>");
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
protected File resolveAbsolutePath(File targetDir, String path, String extension) {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package net.filebot.ui.rename;
|
||||
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.TunedUtilities.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import net.filebot.util.FileUtilities;
|
||||
|
||||
public class TextColorizer {
|
||||
|
||||
private Color pathRainbowBeginColor;
|
||||
private Color pathRainbowEndColor;
|
||||
|
||||
public TextColorizer() {
|
||||
this(new Color(0xCC3300), new Color(0x008080));
|
||||
}
|
||||
|
||||
public TextColorizer(Color pathRainbowBeginColor, Color pathRainbowEndColor) {
|
||||
this.pathRainbowBeginColor = pathRainbowBeginColor;
|
||||
this.pathRainbowEndColor = pathRainbowEndColor;
|
||||
}
|
||||
|
||||
public StringBuilder colorizePath(StringBuilder html, File file, boolean hasExtension) {
|
||||
List<File> path = listPath(file);
|
||||
|
||||
// colorize parent path
|
||||
for (int i = 0; i < path.size() - 1; i++) {
|
||||
float f = (path.size() <= 2) ? 1 : (float) i / (path.size() - 2);
|
||||
Color c = interpolateHSB(pathRainbowBeginColor, pathRainbowEndColor, f);
|
||||
html.append(String.format("<span style='color:rgb(%1$d, %2$d, %3$d)'>%4$s</span><span style='color:rgb(%1$d, %2$d, %3$d)'>/</span>", c.getRed(), c.getGreen(), c.getBlue(), escapeHTML(FileUtilities.getFolderName(path.get(i)))));
|
||||
}
|
||||
|
||||
// only colorize extension
|
||||
if (hasExtension) {
|
||||
html.append(escapeHTML(FileUtilities.getName(file)));
|
||||
String extension = FileUtilities.getExtension(file);
|
||||
if (extension != null) {
|
||||
html.append(String.format("<span style='color:#607080'>.%s</span>", escapeHTML(extension))); // highlight extension
|
||||
}
|
||||
} else {
|
||||
html.append(file.getName());
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
}
|
|
@ -135,8 +135,8 @@ public final class TunedUtilities {
|
|||
return (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
||||
}
|
||||
|
||||
public static List<String> showMultiValueInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
String input = showInputDialog(text, initialValue, title, parent);
|
||||
public static List<String> showMultiValueInputDialog(final Object message, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
String input = showInputDialog(message, initialValue, title, parent);
|
||||
if (input == null || input.isEmpty()) {
|
||||
return emptyList();
|
||||
}
|
||||
|
@ -161,14 +161,14 @@ public final class TunedUtilities {
|
|||
return singletonList(input);
|
||||
}
|
||||
|
||||
public static String showInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
public static String showInputDialog(final Object message, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Object value = JOptionPane.showInputDialog(parent, text, title, PLAIN_MESSAGE, null, null, initialValue);
|
||||
Object value = JOptionPane.showInputDialog(parent, message, title, PLAIN_MESSAGE, null, null, initialValue);
|
||||
if (value != null) {
|
||||
buffer.append(value.toString().trim());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue