* more visual feed back for checksum errors and warnings
This commit is contained in:
parent
87e8d830ce
commit
53c769321e
|
@ -2,6 +2,10 @@
|
||||||
package net.sourceforge.filebot.ui.panel.sfv;
|
package net.sourceforge.filebot.ui.panel.sfv;
|
||||||
|
|
||||||
|
|
||||||
|
import static java.awt.Font.BOLD;
|
||||||
|
import static java.awt.Font.PLAIN;
|
||||||
|
import static net.sourceforge.tuned.ui.TunedUtilities.derive;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
|
||||||
|
@ -32,27 +36,25 @@ public class ChecksumCellRenderer extends DefaultTableCellRenderer {
|
||||||
// ignore focus
|
// ignore focus
|
||||||
super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
||||||
|
|
||||||
// restore text color
|
// check row state for ERROR
|
||||||
setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
|
boolean isError = (table.getValueAt(row, 0) == ChecksumRow.State.ERROR);
|
||||||
|
|
||||||
|
// if row state is ERROR and if we are not selected use text color RED,
|
||||||
|
// else use default table colors
|
||||||
|
setForeground(isSelected ? table.getSelectionForeground() : isError ? Color.RED : table.getForeground());
|
||||||
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
|
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
|
||||||
|
|
||||||
|
// use BOLD font on ERROR
|
||||||
|
setFont(getFont().deriveFont(isError ? BOLD : PLAIN));
|
||||||
|
|
||||||
if (pendingWorker) {
|
if (pendingWorker) {
|
||||||
setText("Pending...");
|
setText("Pending...");
|
||||||
} else if (value == null && !isSelected) {
|
} else if (value == null && !isSelected) {
|
||||||
setBackground(derive(table.getGridColor(), 0.1f));
|
setBackground(derive(table.getGridColor(), 0.1f));
|
||||||
} else if (value instanceof Throwable) {
|
} else if (value instanceof Throwable) {
|
||||||
setText(ExceptionUtilities.getRootCauseMessage((Throwable) value));
|
setText(ExceptionUtilities.getRootCauseMessage((Throwable) value));
|
||||||
|
|
||||||
if (!isSelected) {
|
|
||||||
setForeground(Color.RED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Color derive(Color color, float alpha) {
|
|
||||||
return new Color(((((int) (alpha * 255)) & 0xFF) << 24) & (color.getRGB() | 0xFF000000), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,21 @@ class ChecksumComputationService {
|
||||||
executors.clear();
|
executors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fireTaskCountChanged();
|
pcs.firePropertyChange(TASK_COUNT_PROPERTY, -1, getTaskCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of active executors that are associated with this
|
||||||
|
* {@link ChecksumComputationService}.
|
||||||
|
*
|
||||||
|
* @return number of active executors
|
||||||
|
* @see {@link #newExecutor()}
|
||||||
|
*/
|
||||||
|
public int getActiveCount() {
|
||||||
|
synchronized (executors) {
|
||||||
|
return executors.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +100,7 @@ class ChecksumComputationService {
|
||||||
|
|
||||||
synchronized (executors) {
|
synchronized (executors) {
|
||||||
if (executors.add(this) && executors.size() == 1) {
|
if (executors.add(this) && executors.size() == 1) {
|
||||||
|
// first executor of a new session, reset counts
|
||||||
totalTaskCount.set(0);
|
totalTaskCount.set(0);
|
||||||
completedTaskCount.set(0);
|
completedTaskCount.set(0);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +131,8 @@ class ChecksumComputationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
totalTaskCount.incrementAndGet();
|
totalTaskCount.incrementAndGet();
|
||||||
fireTaskCountChanged();
|
|
||||||
|
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() - 1, getTaskCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,7 +149,8 @@ class ChecksumComputationService {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
// subtract removed tasks from task count
|
// subtract removed tasks from task count
|
||||||
totalTaskCount.addAndGet(-delta);
|
totalTaskCount.addAndGet(-delta);
|
||||||
fireTaskCountChanged();
|
|
||||||
|
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + delta, getTaskCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +166,7 @@ class ChecksumComputationService {
|
||||||
completedTaskCount.incrementAndGet();
|
completedTaskCount.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
fireTaskCountChanged();
|
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + 1, getTaskCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,24 +184,18 @@ class ChecksumComputationService {
|
||||||
executors.remove(this);
|
executors.remove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
|
|
||||||
|
|
||||||
private void fireTaskCountChanged() {
|
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||||
propertyChangeSupport.firePropertyChange(TASK_COUNT_PROPERTY, null, getTaskCount());
|
pcs.addPropertyChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||||
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
|
pcs.removePropertyChangeListener(listener);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
|
||||||
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,4 +66,5 @@ class ChecksumComputationTask extends SwingWorker<Map<HashType, String>, Void> {
|
||||||
|
|
||||||
return Collections.singletonMap(hashType, hash.digest());
|
return Collections.singletonMap(hashType, hash.digest());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
package net.sourceforge.filebot.ui.panel.sfv;
|
package net.sourceforge.filebot.ui.panel.sfv;
|
||||||
|
|
||||||
|
|
||||||
import static net.sourceforge.filebot.ui.panel.sfv.ChecksumTableModel.*;
|
import static net.sourceforge.filebot.ui.panel.sfv.ChecksumTableModel.HASH_TYPE_PROPERTY;
|
||||||
import static net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy.*;
|
import static net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy.LOADING_PROPERTY;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
@ -24,6 +25,7 @@ import javax.swing.JToggleButton;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sourceforge.filebot.ResourceManager;
|
import net.sourceforge.filebot.ResourceManager;
|
||||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||||
|
|
|
@ -163,7 +163,7 @@ class ChecksumRow {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s %s", name, hashes);
|
return String.format("%s %s %s", state, name, hashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PropertyChangeListener updateStateListener = new PropertyChangeListener() {
|
private final PropertyChangeListener updateStateListener = new PropertyChangeListener() {
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
package net.sourceforge.filebot.ui.panel.sfv;
|
package net.sourceforge.filebot.ui.panel.sfv;
|
||||||
|
|
||||||
|
|
||||||
import net.sourceforge.filebot.FileBotUtilities;
|
import static net.sourceforge.filebot.FileBotUtilities.EMBEDDED_CHECKSUM_PATTERN;
|
||||||
import net.sourceforge.tuned.ui.TunedUtilities.DragDropRowTableUI;
|
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
|
|
||||||
|
import net.sourceforge.tuned.ui.TunedUtilities.DragDropRowTableUI;
|
||||||
|
|
||||||
|
|
||||||
class ChecksumTable extends JTable {
|
class ChecksumTable extends JTable {
|
||||||
|
|
||||||
|
@ -26,7 +28,7 @@ class ChecksumTable extends JTable {
|
||||||
setUI(new DragDropRowTableUI());
|
setUI(new DragDropRowTableUI());
|
||||||
|
|
||||||
// highlight CRC32 patterns in filenames in green and with smaller font-size
|
// highlight CRC32 patterns in filenames in green and with smaller font-size
|
||||||
setDefaultRenderer(String.class, new HighlightPatternCellRenderer(FileBotUtilities.EMBEDDED_CHECKSUM_PATTERN, "#009900", "smaller"));
|
setDefaultRenderer(String.class, new HighlightPatternCellRenderer(EMBEDDED_CHECKSUM_PATTERN));
|
||||||
setDefaultRenderer(ChecksumRow.State.class, new StateIconCellRenderer());
|
setDefaultRenderer(ChecksumRow.State.class, new StateIconCellRenderer());
|
||||||
setDefaultRenderer(ChecksumCell.class, new ChecksumCellRenderer());
|
setDefaultRenderer(ChecksumCell.class, new ChecksumCellRenderer());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
import net.sourceforge.tuned.FileUtilities;
|
import net.sourceforge.tuned.FileUtilities;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,10 @@ import javax.swing.table.DefaultTableCellRenderer;
|
||||||
class HighlightPatternCellRenderer extends DefaultTableCellRenderer {
|
class HighlightPatternCellRenderer extends DefaultTableCellRenderer {
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final String cssColor;
|
|
||||||
private final String cssFontSize;
|
|
||||||
|
|
||||||
|
|
||||||
public HighlightPatternCellRenderer(Pattern pattern, String cssColor, String cssFontSize) {
|
public HighlightPatternCellRenderer(Pattern pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.cssColor = cssColor;
|
|
||||||
this.cssFontSize = cssFontSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +27,8 @@ class HighlightPatternCellRenderer extends DefaultTableCellRenderer {
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||||
super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
||||||
|
|
||||||
|
boolean isWarning = (table.getValueAt(row, 0) == ChecksumRow.State.WARNING);
|
||||||
|
|
||||||
// highlight CRC32 checksum patterns by using a smaller font-size and changing the font-color to a dark green
|
// highlight CRC32 checksum patterns by using a smaller font-size and changing the font-color to a dark green
|
||||||
// do not change the font-color if cell is selected, because that would look ugly (imagine green text on blue background ...)
|
// do not change the font-color if cell is selected, because that would look ugly (imagine green text on blue background ...)
|
||||||
Matcher matcher = pattern.matcher(value.toString());
|
Matcher matcher = pattern.matcher(value.toString());
|
||||||
|
@ -39,7 +37,7 @@ class HighlightPatternCellRenderer extends DefaultTableCellRenderer {
|
||||||
StringBuffer htmlText = new StringBuffer("<html><nobr>");
|
StringBuffer htmlText = new StringBuffer("<html><nobr>");
|
||||||
|
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
matcher.appendReplacement(htmlText, createReplacement(isSelected));
|
matcher.appendReplacement(htmlText, createReplacement(isSelected ? null : isWarning ? "#FF8C00" : "#009900", "smaller"));
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher.appendTail(htmlText);
|
matcher.appendTail(htmlText);
|
||||||
|
@ -52,18 +50,21 @@ class HighlightPatternCellRenderer extends DefaultTableCellRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected String createReplacement(boolean isSelected) {
|
protected String createReplacement(String cssColor, String cssFontSize) {
|
||||||
// build replacement string like
|
// build replacement string like
|
||||||
// e.g. <span style='font-size: smaller; color: #009900;'>$0</span>
|
// e.g. <span style='font-size: smaller; color: #009900;'>$0</span>
|
||||||
StringBuilder replacement = new StringBuilder(60);
|
StringBuilder replacement = new StringBuilder(60);
|
||||||
|
|
||||||
replacement.append("<span style='");
|
replacement.append("<span style='");
|
||||||
replacement.append("font-size:").append(cssFontSize).append(';');
|
|
||||||
|
|
||||||
if (!isSelected) {
|
if (cssColor != null) {
|
||||||
replacement.append("color:").append(cssColor).append(';');
|
replacement.append("color:").append(cssColor).append(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cssFontSize != null) {
|
||||||
|
replacement.append("font-size:").append(cssFontSize).append(';');
|
||||||
|
}
|
||||||
|
|
||||||
return replacement.append("'>$0</span>").toString();
|
return replacement.append("'>$0</span>").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
package net.sourceforge.filebot.ui.panel.sfv;
|
package net.sourceforge.filebot.ui.panel.sfv;
|
||||||
|
|
||||||
|
|
||||||
import static net.sourceforge.filebot.ui.panel.sfv.ChecksumComputationService.TASK_COUNT_PROPERTY;
|
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
|
@ -37,7 +35,7 @@ class TotalProgressPanel extends JComponent {
|
||||||
|
|
||||||
add(progressBar, "growx");
|
add(progressBar, "growx");
|
||||||
|
|
||||||
computationService.addPropertyChangeListener(TASK_COUNT_PROPERTY, progressListener);
|
computationService.addPropertyChangeListener(progressListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PropertyChangeListener progressListener = new PropertyChangeListener() {
|
private final PropertyChangeListener progressListener = new PropertyChangeListener() {
|
||||||
|
|
|
@ -43,6 +43,11 @@ public final class TunedUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Color derive(Color color, float alpha) {
|
||||||
|
return new Color(((int) ((alpha * 255)) << 24) | (color.getRGB() & 0x00FFFFFF), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void putActionForKeystroke(JComponent component, KeyStroke keystroke, Action action) {
|
public static void putActionForKeystroke(JComponent component, KeyStroke keystroke, Action action) {
|
||||||
Integer key = action.hashCode();
|
Integer key = action.hashCode();
|
||||||
component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keystroke, key);
|
component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keystroke, key);
|
||||||
|
|
Loading…
Reference in New Issue