From 3a91757e3e87faa30bd504cb1aae1757b82cbf13 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Fri, 29 Feb 2008 01:16:52 +0000 Subject: [PATCH] * improved preferences handling * SelectButton refactoring --- source/net/sourceforge/filebot/Settings.java | 128 +++++++++++------- .../filebot/resources/ResourceManager.java | 11 +- .../sourceforge/filebot/ui/FileBotWindow.java | 4 +- .../panel/rename/RenameListCellRenderer.java | 4 +- .../filebot/ui/panel/search/SearchPanel.java | 47 ++----- .../sourceforge/filebot/web/AnidbClient.java | 1 + .../filebot/web/EpisodeListClient.java | 27 +++- .../sourceforge/filebot/web/TVRageClient.java | 3 +- .../filebot/web/TvdotcomClient.java | 3 +- .../tuned/ui/FancyListCellRenderer.java | 6 +- .../sourceforge/tuned/ui/SelectButton.java | 117 ++++++++++++---- .../tuned/ui/TextFieldWithSelect.java | 12 +- 12 files changed, 237 insertions(+), 126 deletions(-) diff --git a/source/net/sourceforge/filebot/Settings.java b/source/net/sourceforge/filebot/Settings.java index b7b254a4..e641400f 100644 --- a/source/net/sourceforge/filebot/Settings.java +++ b/source/net/sourceforge/filebot/Settings.java @@ -4,9 +4,12 @@ package net.sourceforge.filebot; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; @@ -14,6 +17,10 @@ public class Settings { private static Settings settings = new Settings(); + public static final String SELECTED_PANEL = "panel"; + public static final String SEARCH_HISTORY = "history/search"; + public static final String SUBTITLE_HISTORY = "history/subtitle"; + public static Settings getSettings() { return settings; @@ -23,74 +30,91 @@ public class Settings { private Settings() { - this.prefs = Preferences.userNodeForPackage(this.getClass()); - } - - private String defaultDelimiter = ";"; - - - private void putStringList(String key, Collection values) { - try { - StringBuffer sb = new StringBuffer(); - - for (String value : values) { - sb.append(value.replaceAll(defaultDelimiter, " ")); - sb.append(defaultDelimiter); - } - - prefs.put(key, sb.toString()); - } catch (IllegalArgumentException e) { - // value might exceed max length - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString()); - } + this.prefs = Preferences.userRoot().node("filebot"); } - private Collection getStringList(String key) { - String[] values = prefs.get(key, "").split(defaultDelimiter); + public void putString(String key, String value) { + prefs.put(key, value); + } + + + public String getString(String key, String def) { + return prefs.get(key, def); + } + + + public void putInt(String key, int value) { + prefs.putInt(key, value); + } + + + public int getInt(String key, int def) { + return prefs.getInt(key, def); + } + + + public void putBoolean(String key, boolean value) { + prefs.putBoolean(key, value); + } + + + public boolean getBoolean(String key, boolean def) { + return prefs.getBoolean(key, def); + } + + + public Collection getStringList(String key) { + Preferences listNode = prefs.node(key); List list = new ArrayList(); - for (String value : values) { - if (!value.isEmpty()) - list.add(value); + try { + for (String nodeKey : listNode.keys()) { + list.add(listNode.get(nodeKey, null)); + } + } catch (BackingStoreException e) { + Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString()); } return list; } - - private static enum Key { - panel, tvshowcompletionterms, subtitlecompletionterms; - } - - - public int getSelectedPanel() { - return prefs.getInt(Key.panel.name(), 3); + + public void putStringList(String key, Collection list) { + Preferences listNode = prefs.node(key); + + int i = 0; + + for (String entry : list) { + listNode.put(Integer.toString(i), entry); + i++; + } } - public void setSelectedPanel(int index) { - prefs.putInt(Key.panel.name(), index); + public Map getStringMap(String key) { + Preferences mapNode = prefs.node(key); + + Map map = new HashMap(); + + try { + for (String mapNodeKey : mapNode.keys()) { + map.put(mapNodeKey, mapNode.get(mapNodeKey, null)); + } + } catch (BackingStoreException e) { + Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString()); + } + + return map; } - public void setTvShowCompletionTerms(Collection terms) { - putStringList(Key.tvshowcompletionterms.name(), terms); - } - - - public Collection getTvShowCompletionTerms() { - return getStringList(Key.tvshowcompletionterms.name()); - } - - - public void setSubtitleCompletionTerms(Collection terms) { - putStringList(Key.subtitlecompletionterms.name(), terms); - } - - - public Collection getSubtitleCompletionTerms() { - return getStringList(Key.subtitlecompletionterms.name()); + public void putStringMap(String key, Map map) { + Preferences mapNode = prefs.node(key); + + for (Map.Entry entry : map.entrySet()) { + mapNode.put(entry.getKey(), entry.getValue()); + } } } diff --git a/source/net/sourceforge/filebot/resources/ResourceManager.java b/source/net/sourceforge/filebot/resources/ResourceManager.java index 8b2c2bc3..c6545c1d 100644 --- a/source/net/sourceforge/filebot/resources/ResourceManager.java +++ b/source/net/sourceforge/filebot/resources/ResourceManager.java @@ -6,6 +6,8 @@ import java.awt.Image; import java.io.IOException; import java.net.URL; import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.ImageIcon; @@ -27,8 +29,10 @@ public class ResourceManager { try { return ImageIO.read(getResource(name)); } catch (IOException e) { - return null; + Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString()); } + + return null; } @@ -37,6 +41,11 @@ public class ResourceManager { } + public static ImageIcon getFlagIcon(String countryCode) { + return new ImageIcon(ResourceManager.class.getResource(String.format("flags/%s.gif", countryCode))); + } + + private static URL getResource(String name) { String resource = null; diff --git a/source/net/sourceforge/filebot/ui/FileBotWindow.java b/source/net/sourceforge/filebot/ui/FileBotWindow.java index f26a9cb3..5a83f15f 100644 --- a/source/net/sourceforge/filebot/ui/FileBotWindow.java +++ b/source/net/sourceforge/filebot/ui/FileBotWindow.java @@ -57,7 +57,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener { setSize(760, 615); - selectionListPanel.setSelectedIndex(Settings.getSettings().getSelectedPanel()); + selectionListPanel.setSelectedIndex(Settings.getSettings().getInt(Settings.SELECTED_PANEL, 3)); } @@ -71,7 +71,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener { JComponent c = (JComponent) getContentPane(); c.updateUI(); - Settings.getSettings().setSelectedPanel(selectionListPanel.getSelectedIndex()); + Settings.getSettings().putInt(Settings.SELECTED_PANEL, selectionListPanel.getSelectedIndex()); } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenameListCellRenderer.java b/source/net/sourceforge/filebot/ui/panel/rename/RenameListCellRenderer.java index 43a31722..e44989ae 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/RenameListCellRenderer.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/RenameListCellRenderer.java @@ -20,6 +20,8 @@ class RenameListCellRenderer extends FancyListCellRenderer { public RenameListCellRenderer(ListModel names, ListModel files) { this.names = names; this.files = files; + + setHighlightingEnabled(false); } private Color noMatchGradientBeginColor = Color.decode("#B7B7B7"); @@ -44,7 +46,7 @@ class RenameListCellRenderer extends FancyListCellRenderer { private int getMinLength() { - if (names == null || files == null) + if ((names == null) || (files == null)) return 0; int n1 = names.getSize(); diff --git a/source/net/sourceforge/filebot/ui/panel/search/SearchPanel.java b/source/net/sourceforge/filebot/ui/panel/search/SearchPanel.java index 31dc3a6e..22cb515c 100644 --- a/source/net/sourceforge/filebot/ui/panel/search/SearchPanel.java +++ b/source/net/sourceforge/filebot/ui/panel/search/SearchPanel.java @@ -12,7 +12,6 @@ import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,7 +20,6 @@ import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.DefaultListModel; -import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -41,11 +39,8 @@ import net.sourceforge.filebot.ui.FileBotList; import net.sourceforge.filebot.ui.FileBotPanel; import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.filebot.ui.transfer.SaveAction; -import net.sourceforge.filebot.web.AnidbClient; import net.sourceforge.filebot.web.Episode; import net.sourceforge.filebot.web.EpisodeListClient; -import net.sourceforge.filebot.web.TVRageClient; -import net.sourceforge.filebot.web.TvdotcomClient; import net.sourceforge.tuned.ui.SelectButton; import net.sourceforge.tuned.ui.SelectDialog; import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter; @@ -65,30 +60,24 @@ public class SearchPanel extends FileBotPanel { private TextCompletion searchFieldCompletion; - private List episodeListClients = new ArrayList(); - private JSpinner seasonSpinner; public SearchPanel() { super("Search", ResourceManager.getIcon("panel.search")); - episodeListClients.add(new TvdotcomClient()); - episodeListClients.add(new AnidbClient()); - episodeListClients.add(new TVRageClient()); + List> episodeListClients = new ArrayList>(); - HashMap icons = new HashMap(); - - for (EpisodeListClient searchEngine : episodeListClients) { - icons.put(searchEngine, searchEngine.getIcon()); + for (EpisodeListClient client : EpisodeListClient.getAvailableEpisodeListClients()) { + episodeListClients.add(new SelectButton.Entry(client, client.getIcon())); } - searchField = new TextFieldWithSelect(episodeListClients, icons); + searchField = new TextFieldWithSelect(episodeListClients); searchField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE_PROPERTY, searchFieldListener); searchField.getTextField().setColumns(25); searchFieldCompletion = new TextCompletion(searchField.getTextField()); - searchFieldCompletion.addCompletionTerms(Settings.getSettings().getTvShowCompletionTerms()); + searchFieldCompletion.addCompletionTerms(Settings.getSettings().getStringList(Settings.SEARCH_HISTORY)); searchFieldCompletion.hook(); JPanel mainPanel = new JPanel(new BorderLayout(5, 5)); @@ -224,27 +213,17 @@ public class SearchPanel extends FileBotPanel { private class SpinSearchEngineAction extends AbstractAction { - private int spinOffset; + private int spin; - public SpinSearchEngineAction(int spinOffset) { + public SpinSearchEngineAction(int spin) { super("Spin Search Engine"); - this.spinOffset = spinOffset; + this.spin = spin; } public void actionPerformed(ActionEvent e) { - EpisodeListClient current = searchField.getSelectedValue(); - - int nextIndex = episodeListClients.indexOf(current) + spinOffset; - int maxIndex = episodeListClients.size() - 1; - - if (nextIndex < 0) - nextIndex = maxIndex; - else if (nextIndex > maxIndex) - nextIndex = 0; - - searchField.getSelectButton().setSelectedValue(episodeListClients.get(nextIndex)); + searchField.getSelectButton().spinValue(spin); } } @@ -327,8 +306,9 @@ public class SearchPanel extends FileBotPanel { } catch (Exception e) { tabbedPane.remove(episodeList); - MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage()); - Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString()); + Throwable cause = FileBotUtil.getRootCause(e); + MessageManager.showWarning(cause.getMessage()); + Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, cause.toString()); return; } @@ -356,9 +336,10 @@ public class SearchPanel extends FileBotPanel { } searchFieldCompletion.addCompletionTerm(showname); - Settings.getSettings().setTvShowCompletionTerms(searchFieldCompletion.getCompletionTerms()); + Settings.getSettings().putStringList(Settings.SEARCH_HISTORY, searchFieldCompletion.getCompletionTerms()); String title = showname; + if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS) title += " - Season " + task.getNumberOfSeason(); diff --git a/source/net/sourceforge/filebot/web/AnidbClient.java b/source/net/sourceforge/filebot/web/AnidbClient.java index 50204159..18412d56 100644 --- a/source/net/sourceforge/filebot/web/AnidbClient.java +++ b/source/net/sourceforge/filebot/web/AnidbClient.java @@ -134,4 +134,5 @@ public class AnidbClient extends EpisodeListClient { return new URL("http", host, file); } + } diff --git a/source/net/sourceforge/filebot/web/EpisodeListClient.java b/source/net/sourceforge/filebot/web/EpisodeListClient.java index 7609d2fd..3dfd1cc8 100644 --- a/source/net/sourceforge/filebot/web/EpisodeListClient.java +++ b/source/net/sourceforge/filebot/web/EpisodeListClient.java @@ -3,6 +3,7 @@ package net.sourceforge.filebot.web; import java.net.URL; +import java.util.LinkedHashSet; import java.util.List; import javax.swing.ImageIcon; @@ -10,6 +11,30 @@ import javax.swing.ImageIcon; public abstract class EpisodeListClient { + private static LinkedHashSet registry = new LinkedHashSet(); + + static { + registry.add(new TvdotcomClient()); + registry.add(new AnidbClient()); + registry.add(new TVRageClient()); + } + + + public static Iterable getAvailableEpisodeListClients() { + return registry; + } + + + public static EpisodeListClient forName(String name) { + for (EpisodeListClient client : registry) { + if (name.equals(client.getName())) + return client; + } + + return null; + } + + /** * List of shows */ @@ -25,7 +50,7 @@ public abstract class EpisodeListClient { public abstract List getEpisodeList(String showname, int season) throws Exception; - public abstract URL getEpisodeListUrl(String showname, int season) throws Exception; + public abstract URL getEpisodeListUrl(String showname, int season); public boolean isSingleSeasonSupported() { diff --git a/source/net/sourceforge/filebot/web/TVRageClient.java b/source/net/sourceforge/filebot/web/TVRageClient.java index 5fc400d3..0b303972 100644 --- a/source/net/sourceforge/filebot/web/TVRageClient.java +++ b/source/net/sourceforge/filebot/web/TVRageClient.java @@ -88,7 +88,7 @@ public class TVRageClient extends EpisodeListClient { Matcher seasonMatcher = Pattern.compile("Season (\\d+)").matcher(seasonHeader); if (seasonMatcher.matches()) { - if (season == 0 || season == Integer.parseInt(seasonMatcher.group(1))) { + if ((season == 0) || (season == Integer.parseInt(seasonMatcher.group(1)))) { Matcher saeMatcher = Pattern.compile("(\\d+)x(\\d+)").matcher(seasonAndEpisodeNumber); String seasonNumber = null; @@ -133,4 +133,5 @@ public class TVRageClient extends EpisodeListClient { String file = "/search.php?search=" + qs; return new URL("http", host, file); } + } diff --git a/source/net/sourceforge/filebot/web/TvdotcomClient.java b/source/net/sourceforge/filebot/web/TvdotcomClient.java index 3349d3c4..7af3f2fd 100644 --- a/source/net/sourceforge/filebot/web/TvdotcomClient.java +++ b/source/net/sourceforge/filebot/web/TvdotcomClient.java @@ -119,7 +119,7 @@ public class TvdotcomClient extends EpisodeListClient { @Override - public URL getEpisodeListUrl(String showname, int season) { + public URL getEpisodeListUrl(String showname, int season) { try { String summaryFile = cache.get(showname).getFile(); @@ -139,4 +139,5 @@ public class TvdotcomClient extends EpisodeListClient { return new URL("http", host, file); } + } diff --git a/source/net/sourceforge/tuned/ui/FancyListCellRenderer.java b/source/net/sourceforge/tuned/ui/FancyListCellRenderer.java index 9b699162..f22075e1 100644 --- a/source/net/sourceforge/tuned/ui/FancyListCellRenderer.java +++ b/source/net/sourceforge/tuned/ui/FancyListCellRenderer.java @@ -24,8 +24,6 @@ public class FancyListCellRenderer extends DefaultListCellRenderer { private Color gradientEndColor; - private boolean highlightingEnabled; - private Border defaultBorder; private Border selectedBorder; @@ -36,9 +34,11 @@ public class FancyListCellRenderer extends DefaultListCellRenderer { private Insets padding; + private boolean highlightingEnabled; + public FancyListCellRenderer() { - this(GradientStyle.TOP_TO_BOTTOM, false, new Insets(7, 7, 7, 7), new Insets(1, 1, 0, 1), null); + this(GradientStyle.TOP_TO_BOTTOM, true, new Insets(7, 7, 7, 7), new Insets(1, 1, 0, 1), null); } diff --git a/source/net/sourceforge/tuned/ui/SelectButton.java b/source/net/sourceforge/tuned/ui/SelectButton.java index 168345d2..d56c3c72 100644 --- a/source/net/sourceforge/tuned/ui/SelectButton.java +++ b/source/net/sourceforge/tuned/ui/SelectButton.java @@ -15,8 +15,9 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import java.util.Map; import javax.swing.Icon; import javax.swing.JButton; @@ -35,17 +36,18 @@ public class SelectButton extends JButton implements ActionListener { private Color beginColorHover = beginColor; private Color endColorHover = Color.decode("#D8D7CD"); - private T selectedValue = null; + private Entry selectedEntry = null; - private List options; - private Map icons; + private List> entries = new ArrayList>(); public static final String SELECTED_VALUE_PROPERTY = "SELECTED_VALUE_PROPERTY"; - public SelectButton(List options, Map icons) { - this.options = options; - this.icons = icons; + public SelectButton(Collection> entries) { + if (entries.isEmpty()) + throw new IllegalArgumentException("Entries must not be empty"); + + this.entries.addAll(entries); setContentAreaFilled(false); setFocusable(false); @@ -57,36 +59,70 @@ public class SelectButton extends JButton implements ActionListener { addMouseListener(new MouseInputListener()); - // select first option - setSelectedValue(options.iterator().next()); setPreferredSize(new Dimension(32, 22)); + + // select first entry + setSelectedIndex(0); } public void setSelectedValue(T value) { - if (selectedValue == value) + Entry entry = find(value); + + if (entry == null) return; - T oldSelectedValue = selectedValue; + selectedEntry = entry; + setIcon(new SelectIcon(selectedEntry.getIcon())); - selectedValue = value; - Icon icon = icons.get(selectedValue); - setIcon(new SelectIcon(icon)); - - firePropertyChange(SELECTED_VALUE_PROPERTY, oldSelectedValue, selectedValue); + firePropertyChange(SELECTED_VALUE_PROPERTY, null, selectedEntry); } - public T getSelectedValue() { - return selectedValue; + public T getSelectedEntry() { + return selectedEntry.getValue(); + } + + + public void setSelectedIndex(int i) { + setSelectedValue(entries.get(i).getValue()); + } + + + public int getSelectedIndex() { + return entries.indexOf(selectedEntry); + } + + + private Entry find(T value) { + for (Entry entry : entries) { + if (entry.value == value) + return entry; + } + + return null; + } + + + public void spinValue(int spin) { + spin = spin % entries.size(); + + int next = getSelectedIndex() + spin; + + if (next < 0) + next += entries.size(); + else if (next >= entries.size()) + next -= entries.size(); + + setSelectedIndex(next); } public void actionPerformed(ActionEvent e) { JPopupMenu popup = new JPopupMenu(); - for (T option : options) { - popup.add(new SelectMenuIem(option)); + for (Entry entry : entries) { + popup.add(new SelectMenuItem(entry)); } popup.show(this, 0, getHeight() - 1); @@ -108,22 +144,24 @@ public class SelectButton extends JButton implements ActionListener { } - private class SelectMenuIem extends JMenuItem implements ActionListener { + private class SelectMenuItem extends JMenuItem implements ActionListener { private T value; - public SelectMenuIem(T value) { - super(value.toString(), icons.get(value)); - this.value = value; + public SelectMenuItem(Entry entry) { + super(entry.toString(), entry.getIcon()); + this.value = entry.getValue(); + this.setMargin(new Insets(3, 0, 3, 0)); this.addActionListener(this); - if (this.value == getSelectedValue()) + if (this.value == getSelectedEntry()) this.setFont(this.getFont().deriveFont(Font.BOLD)); } + @Override public void actionPerformed(ActionEvent e) { setSelectedValue(value); } @@ -189,4 +227,33 @@ public class SelectButton extends JButton implements ActionListener { } + + public static class Entry { + + private T value; + private Icon icon; + + + public Entry(T value, Icon icon) { + this.value = value; + this.icon = icon; + } + + + public T getValue() { + return value; + } + + + public Icon getIcon() { + return icon; + } + + + @Override + public String toString() { + return value.toString(); + } + } + } diff --git a/source/net/sourceforge/tuned/ui/TextFieldWithSelect.java b/source/net/sourceforge/tuned/ui/TextFieldWithSelect.java index e15bcb13..83dd9c51 100644 --- a/source/net/sourceforge/tuned/ui/TextFieldWithSelect.java +++ b/source/net/sourceforge/tuned/ui/TextFieldWithSelect.java @@ -6,15 +6,15 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.List; -import java.util.Map; +import java.util.Collection; import javax.swing.BorderFactory; -import javax.swing.Icon; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.Border; +import net.sourceforge.tuned.ui.SelectButton.Entry; + public class TextFieldWithSelect extends JPanel { @@ -24,10 +24,10 @@ public class TextFieldWithSelect extends JPanel { private Color borderColor = Color.decode("#A4A4A4"); - public TextFieldWithSelect(List options, Map icons) { + public TextFieldWithSelect(Collection> options) { setLayout(new BorderLayout(0, 0)); - selectButton = new SelectButton(options, icons); + selectButton = new SelectButton(options); selectButton.addActionListener(textFieldFocusOnClick); Border lineBorder = BorderFactory.createLineBorder(borderColor, 1); @@ -54,7 +54,7 @@ public class TextFieldWithSelect extends JPanel { public T getSelectedValue() { - return selectButton.getSelectedValue(); + return selectButton.getSelectedEntry(); }