* added mismatch highlighting

This commit is contained in:
Reinhard Pointner 2011-11-27 14:39:58 +00:00
parent 90d9887c20
commit 431044eca4
5 changed files with 66 additions and 22 deletions

View File

@ -46,7 +46,6 @@ import net.sourceforge.filebot.hash.VerificationFileWriter;
import net.sourceforge.filebot.similarity.EpisodeMetrics;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.similarity.Matcher;
import net.sourceforge.filebot.similarity.MetricCascade;
import net.sourceforge.filebot.similarity.NameSimilarityMetric;
import net.sourceforge.filebot.similarity.SeriesNameMatcher;
import net.sourceforge.filebot.similarity.SimilarityMetric;
@ -384,7 +383,7 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine("Looking up subtitles by filehash via " + service.getName());
collector.addAll(service.getName(), lookupSubtitleByHash(service, language, collector.remainingVideos()));
} catch (RuntimeException e) {
} catch (Exception e) {
CLILogger.warning(format("Lookup by hash failed: " + e.getMessage()));
}
}
@ -402,7 +401,7 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine(format("Searching for %s at [%s]", querySet.toString(), service.getName()));
collector.addAll(service.getName(), lookupSubtitleByFileName(service, querySet, language, collector.remainingVideos()));
} catch (RuntimeException e) {
} catch (Exception e) {
CLILogger.warning(format("Search for [%s] failed: %s", querySet, e.getMessage()));
}
}
@ -499,7 +498,7 @@ public class CmdlineOperations implements CmdlineInterface {
if (subtitles.size() > 0) {
// first match everything as best as possible, then filter possibly bad matches
Matcher<File, SubtitleDescriptor> matcher = new Matcher<File, SubtitleDescriptor>(videoFiles, subtitles, false, EpisodeMetrics.defaultSequence(true));
SimilarityMetric sanity = new MetricCascade(StrictEpisodeMetrics.defaultSequence(true));
SimilarityMetric sanity = EpisodeMetrics.verificationMetric();
for (Match<File, SubtitleDescriptor> it : matcher.match()) {
if (sanity.getSimilarity(it.getValue(), it.getCandidate()) >= 1) {

View File

@ -2,6 +2,9 @@
package net.sourceforge.filebot.ui.rename;
import static net.sourceforge.filebot.similarity.EpisodeMetrics.*;
import static net.sourceforge.tuned.ui.TunedUtilities.*;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
@ -19,7 +22,9 @@ import javax.swing.border.EmptyBorder;
import net.miginfocom.swing.MigLayout;
import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.ui.rename.RenameModel.FormattedFuture;
import net.sourceforge.filebot.web.Episode;
import net.sourceforge.tuned.FileUtilities;
import net.sourceforge.tuned.ui.DefaultFancyListCellRenderer;
import net.sourceforge.tuned.ui.GradientStyle;
@ -34,16 +39,18 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
private final Color noMatchGradientBeginColor = new Color(0xB7B7B7);
private final Color noMatchGradientEndColor = new Color(0x9A9A9A);
private final Color warningGradientBeginColor = Color.RED;
private final Color warningGradientEndColor = new Color(0xDC143C);
public RenameListCellRenderer(RenameModel renameModel) {
super(new Insets(4, 7, 4, 7));
this.renameModel = renameModel;
setHighlightingEnabled(false);
setLayout(new MigLayout("insets 0, fill", "align left", "align center"));
add(typeRenderer, "gap rel:push, hidemode 3");
this.add(typeRenderer, "gap rel:push, hidemode 3");
}
@ -51,7 +58,8 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
// reset decoration
// reset decoration / highlighting
setOpaque(false);
setIcon(null);
typeRenderer.setVisible(false);
typeRenderer.setAlpha(1.0f);
@ -80,6 +88,7 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
} else if (value instanceof FormattedFuture) {
// display progress icon
FormattedFuture formattedFuture = (FormattedFuture) value;
setText(formattedFuture.isDone() && !formattedFuture.isCancelled() ? formattedFuture.toString() : formattedFuture.preview());
switch (formattedFuture.getState()) {
case PENDING:
@ -89,10 +98,45 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
setIcon(ResourceManager.getIcon("worker.started"));
break;
}
if (renameModel.hasComplement(index)) {
float matchProbablity = getMatchProbablity(formattedFuture.getMatch());
setOpaque(true); // enable paint background
setBackground(derive(warningGradientBeginColor, (1 - matchProbablity) * 0.5f)); // alpha indicates match probability
if (matchProbablity < 1) {
if (isSelected) {
setGradientColors(warningGradientBeginColor, warningGradientEndColor);
setIcon(ResourceManager.getIcon("status.warning"));
if (formattedFuture.isComplexFormat()) {
typeRenderer.setVisible(true);
typeRenderer.setAlpha(1.0f);
typeRenderer.setText(formattedFuture.preview());
}
}
}
}
}
}
protected float getMatchProbablity(Match<Object, File> match) {
if (match.getValue() instanceof Episode) {
float f = verificationMetric().getSimilarity(match.getValue(), match.getCandidate());
return (f + 1) / 2; // normalize -1..1 to 0..1
}
float f = EpisodeIdentifier.getSimilarity(match.getValue(), match.getCandidate());
if (f != 0) {
return (Math.max(f, 0)); // normalize -1..1 and boost by 0.25 (because file <-> file matches are not necessarily about Episodes)
}
return 1; // assume match is OK
}
protected String getType(File file) {
if (file.isDirectory())
return "Folder";

View File

@ -32,7 +32,7 @@ import net.sourceforge.tuned.ui.TunedUtilities;
public class RenameModel extends MatchModel<Object, File> {
private final FormattedFutureEventList names = new FormattedFutureEventList();
private final FormattedFutureEventList names = new FormattedFutureEventList(this.values());
private final Map<Object, MatchFormatter> formatters = new LinkedHashMap<Object, MatchFormatter>();
@ -151,10 +151,9 @@ public class RenameModel extends MatchModel<Object, File> {
private final Executor backgroundFormatter = new ThreadPoolExecutor(0, 1, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
public FormattedFutureEventList() {
super(values());
source.addListEventListener(this);
public FormattedFutureEventList(EventList<Object> source) {
super(source);
this.source.addListEventListener(this);
}
@ -317,6 +316,11 @@ public class RenameModel extends MatchModel<Object, File> {
}
public boolean isComplexFormat() {
return formatter instanceof ExpressionFormatter;
}
public Match<Object, File> getMatch() {
return match;
}

View File

@ -4,7 +4,6 @@ package net.sourceforge.filebot.ui.subtitle;
import static javax.swing.BorderFactory.*;
import static javax.swing.JOptionPane.*;
import static net.sourceforge.filebot.similarity.EpisodeMetrics.*;
import static net.sourceforge.filebot.subtitle.SubtitleUtilities.*;
import static net.sourceforge.tuned.FileUtilities.*;
@ -60,10 +59,8 @@ import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.similarity.EpisodeMetrics;
import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.similarity.Matcher;
import net.sourceforge.filebot.similarity.MetricCascade;
import net.sourceforge.filebot.similarity.SeriesNameMatcher;
import net.sourceforge.filebot.similarity.SimilarityMetric;
import net.sourceforge.filebot.similarity.StrictEpisodeMetrics;
import net.sourceforge.filebot.ui.Language;
import net.sourceforge.filebot.vfs.MemoryFile;
import net.sourceforge.filebot.web.SubtitleDescriptor;
@ -927,7 +924,7 @@ class VideoHashSubtitleDownloadDialog extends JDialog {
// first match everything as best as possible, then filter possibly bad matches
Matcher<File, SubtitleDescriptor> matcher = new Matcher<File, SubtitleDescriptor>(files, subtitles, false, EpisodeMetrics.defaultSequence(true));
SimilarityMetric sanity = new MetricCascade(StrictEpisodeMetrics.defaultSequence(true));
SimilarityMetric sanity = EpisodeMetrics.verificationMetric();
for (Match<File, SubtitleDescriptor> it : matcher.match()) {
if (sanity.getSimilarity(it.getValue(), it.getCandidate()) >= 1) {
@ -936,13 +933,12 @@ class VideoHashSubtitleDownloadDialog extends JDialog {
}
// add other possible matches to the options
SimilarityMetric matchMetric = new MetricCascade(FileName, EpisodeIdentifier, Title, Name);
float matchSimilarity = 0.6f;
float minMatchSimilarity = 0.6f;
for (File file : files) {
// add matching subtitles
for (SubtitleDescriptor it : subtitles) {
if (matchMetric.getSimilarity(file, it) >= matchSimilarity && !subtitlesByFile.get(file).contains(it)) {
if (!subtitlesByFile.get(file).contains(it) && sanity.getSimilarity(file, it) >= minMatchSimilarity) {
subtitlesByFile.get(file).add(it);
}
}

View File

@ -15,20 +15,23 @@ public class DefaultFancyListCellRenderer extends AbstractFancyListCellRenderer
private final JLabel label = new DefaultListCellRenderer();
public DefaultFancyListCellRenderer() {
add(label);
}
public DefaultFancyListCellRenderer(int padding) {
super(new Insets(padding, padding, padding, padding));
add(label);
}
public DefaultFancyListCellRenderer(Insets padding) {
super(padding);
add(label);
}
protected DefaultFancyListCellRenderer(int padding, int margin, Color selectedBorderColor) {
super(new Insets(padding, padding, padding, padding), new Insets(margin, margin, margin, margin), selectedBorderColor);
@ -39,9 +42,7 @@ public class DefaultFancyListCellRenderer extends AbstractFancyListCellRenderer
@Override
protected void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
label.setOpaque(false);
setText(String.valueOf(value));
}