* didn't add some files in last commit ...

This commit is contained in:
Reinhard Pointner 2009-05-31 16:30:48 +00:00
parent a547c7e7e9
commit ffc6a8b931
7 changed files with 573 additions and 0 deletions

View File

@ -0,0 +1,64 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import static java.awt.BasicStroke.*;
import static java.awt.RenderingHints.*;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import javax.swing.border.Border;
class DashedSeparator implements Border {
private final int height;
private final int dash;
private final Color foreground;
private final Color background;
public DashedSeparator(int height, int dash, Color foreground, Color background) {
this.height = height;
this.dash = dash;
this.foreground = foreground;
this.background = background;
}
@Override
public Insets getBorderInsets(Component c) {
return new Insets(0, 0, height, 0);
}
@Override
public boolean isBorderOpaque() {
return true;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
Graphics2D g2d = (Graphics2D) g.create(x, h - this.height, w, h);
// fill background
g2d.setPaint(background);
g2d.fillRect(0, 0, w, h);
// draw dashed line
g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
g2d.setColor(foreground);
g2d.setStroke(new BasicStroke(1, CAP_ROUND, JOIN_ROUND, 1, new float[] { dash }, 0));
g2d.drawLine(dash, this.height / 2, w - dash, this.height / 2);
g2d.dispose();
}
}

View File

@ -0,0 +1,50 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import java.awt.Color;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.ResourceManager;
class LanguageComboBoxCellRenderer extends DefaultListCellRenderer {
private final Border padding = new EmptyBorder(2, 2, 2, 2);
private final Border favoritePadding = new EmptyBorder(0, 6, 0, 6);
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
Language language = (Language) value;
setText(language.getName());
setIcon(ResourceManager.getFlagIcon(language.getCode()));
// default padding
setBorder(padding);
LanguageComboBoxModel model = (LanguageComboBoxModel) list.getModel();
if ((index > 0 && index <= model.favorites().size())) {
// add favorite padding
setBorder(new CompoundBorder(favoritePadding, getBorder()));
}
if (index == 0 || index == model.favorites().size()) {
// add separator border
setBorder(new CompoundBorder(new DashedSeparator(10, 4, Color.lightGray, list.getBackground()), getBorder()));
}
return this;
}
}

View File

@ -0,0 +1,188 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import static net.sourceforge.filebot.ui.panel.subtitle.Language.*;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
class LanguageComboBoxModel extends AbstractListModel implements ComboBoxModel {
public static final Language ALL_LANGUAGES = new Language("undefined", "All Languages");
private Language selection = ALL_LANGUAGES;
private List<Language> favorites = new Favorites(2);
private List<Language> values;
public LanguageComboBoxModel() {
values = Arrays.asList(availableLanguages());
// sort languages by name
Collections.sort(values, ALPHABETIC_ORDER);
}
@Override
public Language getElementAt(int index) {
// "All Languages"
if (index == 0) {
return ALL_LANGUAGES;
}
// "All Languages" offset
index -= 1;
if (index < favorites.size()) {
return favorites.get(index);
}
// "Favorites" offset
index -= favorites.size();
return values.get(index);
}
@Override
public int getSize() {
// "All Languages" : favorites[] : values[]
return 1 + favorites.size() + values.size();
}
public List<Language> favorites() {
return favorites;
}
@Override
public Language getSelectedItem() {
return selection;
}
@Override
public void setSelectedItem(Object value) {
if (value instanceof Language) {
selection = (Language) value;
}
}
protected int convertFavoriteIndexToModel(int favoriteIndex) {
return 1 + favoriteIndex;
}
protected void fireFavoritesAdded(int from, int to) {
fireIntervalAdded(this, convertFavoriteIndexToModel(from), convertFavoriteIndexToModel(to));
}
protected void fireFavoritesRemoved(int from, int to) {
fireIntervalRemoved(this, convertFavoriteIndexToModel(from), convertFavoriteIndexToModel(to));
}
private class Favorites extends AbstractList<Language> implements Set<Language> {
private final List<Language> data;
private final int capacity;
public Favorites(int capacity) {
this.data = new ArrayList<Language>(capacity);
this.capacity = capacity;
}
@Override
public Language get(int index) {
return data.get(index);
}
public boolean add(Language element) {
// add first
return addIfAbsent(0, element);
}
public void add(int index, Language element) {
addIfAbsent(index, element);
}
public boolean addIfAbsent(int index, Language element) {
// 1. ignore null values
// 2. ignore ALL_LANGUAGES
// 3. make sure there are no duplicates
// 4. limit size to capacity
if (element == null || element == ALL_LANGUAGES || contains(element) || index >= capacity) {
return false;
}
// make sure there is free space
if (data.size() >= capacity) {
// remove last
remove(data.size() - 1);
}
// add clone of language, because KeySelection behaviour will
// get weird if the same object is in the model multiple times
data.add(index, element.clone());
// update view
fireFavoritesAdded(index, index);
return true;
}
@Override
public boolean contains(Object obj) {
// check via language code, because data consists of clones
if (obj instanceof Language) {
Language language = (Language) obj;
for (Language element : data) {
if (language.getCode().equals(element.getCode()))
return true;
}
}
return false;
}
@Override
public Language remove(int index) {
Language old = data.remove(index);
// update view
fireFavoritesRemoved(index, index);
return old;
}
@Override
public int size() {
return data.size();
}
}
}

View File

@ -0,0 +1,52 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import static java.awt.event.ItemEvent.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
class PopupSelectionListener implements PopupMenuListener, ItemListener {
private Object selected = null;
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JComboBox comboBox = (JComboBox) e.getSource();
// selected item before popup
selected = comboBox.getSelectedItem();
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
JComboBox comboBox = (JComboBox) e.getSource();
// check selected item after popup
if (selected != comboBox.getSelectedItem()) {
itemStateChanged(new ItemEvent(comboBox, ITEM_STATE_CHANGED, comboBox.getSelectedItem(), SELECTED));
}
selected = null;
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
selected = null;
}
@Override
public void itemStateChanged(ItemEvent e) {
}
}

View File

@ -0,0 +1,95 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import java.awt.Color;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JProgressBar;
import javax.swing.border.CompoundBorder;
import net.miginfocom.swing.MigLayout;
import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.tuned.ui.AbstractFancyListCellRenderer;
public class SubtitleListCellRenderer extends AbstractFancyListCellRenderer {
private final JLabel titleLabel = new JLabel();
private final JLabel languageLabel = new JLabel();
private final JProgressBar progressBar = new JProgressBar(0, 100);
private final Map<String, String> languageCodeMap = mapLanguageCodeByName(Language.availableLanguages());
public SubtitleListCellRenderer() {
setHighlightingEnabled(false);
progressBar.setStringPainted(true);
progressBar.setOpaque(false);
progressBar.setPreferredSize(new Dimension(80, 18));
setLayout(new MigLayout("fill, nogrid, insets 0"));
add(languageLabel, "hidemode 3, w 85px!");
add(titleLabel, "");
add(progressBar, "gap indent:push");
setBorder(new CompoundBorder(new DashedSeparator(2, 4, Color.lightGray, Color.white), getBorder()));
}
@Override
public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
SubtitlePackage subtitle = (SubtitlePackage) value;
titleLabel.setIcon(ResourceManager.getIcon("status.archive"));
titleLabel.setText(subtitle.getName());
if (languageLabel.isVisible()) {
languageLabel.setText(subtitle.getLanguageName());
languageLabel.setIcon(ResourceManager.getFlagIcon(languageCodeMap.get(subtitle.getLanguageName())));
}
//TODO download + progress
progressBar.setVisible(false);
progressBar.setString(subtitle.getDownloadTask().getState().toString().toLowerCase());
titleLabel.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
languageLabel.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
// don't paint border on last element
setBorderPainted(index < list.getModel().getSize() - 1);
}
private Map<String, String> mapLanguageCodeByName(Language[] languages) {
Map<String, String> map = new HashMap<String, String>();
for (Language language : languages) {
map.put(language.getName(), language.getCode());
}
return map;
}
public JLabel getLanguageLabel() {
return languageLabel;
}
@Override
public void validate() {
// validate children, yet avoid flickering of the mouse cursor
validateTree();
}
}

View File

@ -0,0 +1,79 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import net.sourceforge.filebot.ResourceManager;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.ListSelection;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.swing.EventListModel;
import ca.odell.glazedlists.swing.EventSelectionModel;
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
public class SubtitleListComponent extends JComponent {
private EventList<SubtitlePackage> model = new BasicEventList<SubtitlePackage>();
private SubtitleListCellRenderer renderer = new SubtitleListCellRenderer();
private JTextField filterEditor = new JTextField();
public SubtitleListComponent() {
TextFilterator<SubtitlePackage> filterator = GlazedLists.toStringTextFilterator();
TextComponentMatcherEditor<SubtitlePackage> matcherEditor = new TextComponentMatcherEditor<SubtitlePackage>(filterEditor, filterator);
JList list = new JList(new EventListModel<SubtitlePackage>(new FilterList<SubtitlePackage>(model, matcherEditor)));
list.setCellRenderer(renderer);
list.setFixedCellHeight(35);
EventSelectionModel<SubtitlePackage> selectionModel = new EventSelectionModel<SubtitlePackage>(model);
selectionModel.setSelectionMode(ListSelection.MULTIPLE_INTERVAL_SELECTION_DEFENSIVE);
list.setSelectionModel(selectionModel);
JButton clearButton = new JButton(clearFilterAction);
clearButton.setOpaque(false);
setLayout(new MigLayout("fill, nogrid", "[fill]", "[pref!][fill]"));
add(new JLabel("Filter:"), "gap indent:push");
add(filterEditor, "wmin 120px, gap rel");
add(clearButton, "w 24px!, h 24px!");
add(new JScrollPane(list), "newline");
}
public EventList<SubtitlePackage> getModel() {
return model;
}
public void setLanguageVisible(boolean visible) {
renderer.getLanguageLabel().setVisible(visible);
}
private final Action clearFilterAction = new AbstractAction(null, ResourceManager.getIcon("edit.clear")) {
@Override
public void actionPerformed(ActionEvent e) {
filterEditor.setText("");
}
};
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<languages>
<language code="sq" name="Albanian" />
<language code="ar" name="Arabic" />
<language code="hy" name="Armenian" />
<language code="pb" name="Brazilian" />
<language code="bg" name="Bulgarian" />
<language code="ca" name="Catalan" />
<language code="zh" name="Chinese" />
<language code="hr" name="Croatian" />
<language code="cs" name="Czech" />
<language code="da" name="Danish" />
<language code="nl" name="Dutch" />
<language code="en" name="English" />
<language code="et" name="Estonian" />
<language code="fi" name="Finnish" />
<language code="fr" name="French" />
<language code="de" name="German" />
<language code="el" name="Greek" />
<language code="he" name="Hebrew" />
<language code="hi" name="Hindi" />
<language code="hu" name="Hungarian" />
<language code="id" name="Indonesian" />
<language code="it" name="Italian" />
<language code="ja" name="Japanese" />
<language code="ko" name="Korean" />
<language code="lv" name="Latvian" />
<language code="lt" name="Lithuanian" />
<language code="mk" name="Macedonian" />
<language code="ms" name="Malay" />
<language code="no" name="Norwegian" />
<language code="fa" name="Persian" />
<language code="pl" name="Polish" />
<language code="pt" name="Portuguese" />
<language code="ro" name="Romanian" />
<language code="ru" name="Russian" />
<language code="sr" name="Serbian" />
<language code="sk" name="Slovak" />
<language code="sl" name="Slovenian" />
<language code="es" name="Spanish" />
<language code="sv" name="Swedish" />
<language code="th" name="Thai" />
<language code="tr" name="Turkish" />
<language code="vi" name="Vietnamese" />
</languages>