1 package com.melloware.jukes.gui.view;
2
3 import java.awt.BorderLayout;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.text.SimpleDateFormat;
7 import java.util.Date;
8 import java.util.List;
9 import java.util.Locale;
10
11 import javax.swing.AbstractButton;
12 import javax.swing.JCheckBox;
13 import javax.swing.JComboBox;
14 import javax.swing.JComponent;
15 import javax.swing.JPanel;
16 import javax.swing.JScrollPane;
17 import javax.swing.JTextField;
18 import javax.swing.JToolBar;
19
20 import org.apache.commons.lang.StringEscapeUtils;
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import com.jgoodies.forms.builder.PanelBuilder;
26 import com.jgoodies.forms.layout.CellConstraints;
27 import com.jgoodies.forms.layout.FormLayout;
28 import com.jgoodies.uif.application.Application;
29 import com.jgoodies.uif.builder.ToolBarBuilder;
30 import com.jgoodies.uifextras.util.UIFactory;
31 import com.melloware.jukes.file.tag.MusicTag;
32 import com.melloware.jukes.gui.tool.Actions;
33 import com.melloware.jukes.gui.tool.MainModule;
34 import com.melloware.jukes.gui.tool.Resources;
35 import com.melloware.jukes.gui.tool.Settings;
36 import com.melloware.jukes.gui.view.component.ComplexInternalFrame;
37 import com.melloware.jukes.gui.view.component.ComponentFactory;
38 import com.melloware.jukes.util.GuiUtil;
39 import com.melloware.jukes.util.TimeSpan;
40 import com.melloware.jukes.util.TimeSpanUnit;
41
42
43
44
45
46
47
48
49 @SuppressWarnings("unchecked")
50 public final class FilterPanel extends ComplexInternalFrame implements ActionListener {
51
52 private static final Log LOG = LogFactory.getLog(FilterPanel.class);
53 private static final String GENRE_NONE = "<none>";
54 private AbstractButton filterButton;
55 private final JCheckBox newFlag;
56 private final JCheckBox exactFlag;
57 private final JComboBox bitrateField;
58 private final JComboBox genreField;
59 private final JComboBox operatorBitrate;
60 private final JComboBox operatorYear;
61 private final JPanel filterPanel;
62 private final JScrollPane scrollPane;
63 private final JTextField yearField1;
64 private final JTextField yearField2;
65 private final Settings settings;
66
67 private final JTextField artistField;
68 private final JTextField albumField;
69
70
71
72
73
74
75 public FilterPanel(Settings settings) {
76 super(Resources.getString("label.filter"));
77 LOG.debug("Filter panel created.");
78 this.settings = settings;
79 setFrameIcon(Resources.FILTER_ICON);
80 setToolBar(buildToolBar());
81
82 final List genres = MusicTag.getGenreTypes();
83 genres.add(0, GENRE_NONE);
84 genreField = new JComboBox(genres.toArray());
85 genreField.setSelectedItem(GENRE_NONE);
86 genreField.setEditable(true);
87 genreField.addActionListener(this);
88 bitrateField = new JComboBox(Resources.BITRATES);
89 bitrateField.setSelectedItem(null);
90 bitrateField.addActionListener(this);
91 operatorBitrate = new JComboBox(Resources.OPERATOR);
92 operatorBitrate.setSelectedItem(">=");
93 operatorBitrate.addActionListener(this);
94 operatorYear = new JComboBox(Resources.OPERATOR);
95 operatorYear.setSelectedItem(">=");
96 operatorYear.addActionListener(this);
97 yearField1 = new JTextField();
98 (yearField1).setColumns(5);
99 yearField2 = new JTextField();
100 (yearField2).setColumns(5);
101 newFlag = new JCheckBox(Resources.getString("label.recentadds"), false);
102 newFlag.addActionListener(this);
103
104 exactFlag = new JCheckBox(Resources.getString("label.exact"), false);
105 exactFlag.addActionListener(this);
106 artistField = new JTextField();
107 (artistField).setColumns(5);
108 albumField = new JTextField();
109 (albumField).setColumns(5);
110
111 filterPanel = new JPanel(new BorderLayout());
112 filterPanel.add(buildFilter(), BorderLayout.CENTER);
113 scrollPane = UIFactory.createStrippedScrollPane(filterPanel);
114 this.add(scrollPane);
115 }
116
117
118
119
120 public void actionPerformed(ActionEvent aEvent) {
121 if (filterButton.isSelected()) {
122 LOG.debug("Filter changed");
123 applyFilter();
124 }
125 }
126
127
128
129
130 public void applyFilter() {
131 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
132 try {
133 GuiUtil.setBusyCursor(mainFrame, true);
134 String query = "";
135
136
137 final String artist = artistField.getText();
138 if (StringUtils.isNotBlank(artist)) {
139 final String artistStmt = artist.replaceAll("'", "\'\'");
140
141
142
143
144 if (exactFlag.isSelected()) {
145 query = query + "and UPPER(artist.name) = '" + artistStmt.toUpperCase() + "'";
146 } else {
147 query = query + "and UPPER(artist.name) LIKE '%" + artistStmt.toUpperCase() + "%'";
148 }
149 }
150 final String album = albumField.getText();
151 if (StringUtils.isNotBlank(album)) {
152 final String albumStmt = album.replaceAll("'", "\'\'");
153
154
155
156 if (exactFlag.isSelected()) {
157 query = query + "and UPPER(disc.name) = '" + albumStmt.toUpperCase() + "'";
158 } else {
159 query = query + "and UPPER(disc.name) LIKE '%" + albumStmt.toUpperCase() + "%'";
160 }
161 }
162 final String genre = (String) genreField.getSelectedItem();
163 if ((StringUtils.isNotBlank(genre)) && (!StringUtils.equals(genre, GENRE_NONE))) {
164
165 if (exactFlag.isSelected()) {
166 query = query + " and UPPER(disc.genre) = '" + genre.toUpperCase() + "'";
167 } else {
168 query = query + " and UPPER(disc.genre) LIKE '%" + genre.toUpperCase() + "%'";
169 }
170 }
171 if (StringUtils.isNotBlank(yearField1.getText())) {
172 if (StringUtils.isBlank(yearField2.getText())) {
173 query = query + " and disc.year " + operatorYear.getSelectedItem().toString()
174 + StringEscapeUtils.escapeSql(yearField1.getText());
175 } else {
176 query = query + " and disc.year between " + StringEscapeUtils.escapeSql(yearField1.getText()) + " and "
177 + StringEscapeUtils.escapeSql(yearField2.getText());
178 }
179 }
180 if (bitrateField.getSelectedItem() != null) {
181 query = query + " and disc.bitrate " + operatorBitrate.getSelectedItem().toString()
182 + StringEscapeUtils.escapeSql((String) bitrateField.getSelectedItem());
183 }
184 if (newFlag.isSelected()) {
185 final TimeSpan timespan = new TimeSpan(System.currentTimeMillis());
186 timespan.subtract(TimeSpanUnit.DAYS, this.settings.getNewFileInDays());
187 final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
188 query = query + " and disc.createdDate > '" + format.format(new Date(timespan.getTime())) + " 00:00:00'";
189 }
190
191 MainModule.SETTINGS.setFilter(query);
192 mainFrame.getMainModule().refreshTree();
193 } finally {
194 GuiUtil.setBusyCursor(mainFrame, false);
195 }
196 }
197
198
199
200
201 public void clearFilter() {
202 genreField.setSelectedItem(null);
203 yearField1.setText("");
204 yearField2.setText("");
205
206 artistField.setText("");
207 albumField.setText("");
208
209 bitrateField.setSelectedItem(null);
210 newFlag.setSelected(false);
211 exactFlag.setSelected(false);
212
213 filterButton.setSelected(false);
214 removeFilter();
215 }
216
217
218
219
220 public void removeFilter() {
221 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
222 try {
223 GuiUtil.setBusyCursor(mainFrame, true);
224 MainModule.SETTINGS.setFilter("");
225 mainFrame.getMainModule().refreshTree();
226 } finally {
227 GuiUtil.setBusyCursor(mainFrame, false);
228 }
229 }
230
231
232
233
234
235
236 private JComponent buildFilter() {
237 FormLayout layout = new FormLayout("3px, pref, pref, pref, pref, fill:pref:grow",
238 "4px, p, 4px, p, 4px, p, 4px, p, 4px, p, 4px, p, 4px, p");
239 PanelBuilder builder = new PanelBuilder(layout);
240 CellConstraints cc = new CellConstraints();
241
242 builder.addLabel(Resources.getString("label.artist") + ": ", cc.xy(2, 2));
243 builder.add(artistField, cc.xyw(3, 2, 4));
244 builder.addLabel(Resources.getString("label.disc") + ": ", cc.xy(2, 4));
245 builder.add(albumField, cc.xyw(3, 4, 4));
246 builder.addLabel(Resources.getString("label.genre") + ": ", cc.xy(2, 6));
247 builder.add(genreField, cc.xyw(3, 6, 4));
248 builder.addLabel(Resources.getString("label.year") + ": ", cc.xy(2, 8));
249 builder.add(operatorYear, cc.xy(3, 8));
250 builder.add(yearField1, cc.xy(4, 8));
251 builder.add(yearField2, cc.xy(5, 8));
252 builder.addLabel(Resources.getString("label.bitrate") + ": ", cc.xy(2, 10));
253 builder.add(operatorBitrate, cc.xy(3, 10));
254 builder.add(bitrateField, cc.xy(4, 10));
255 builder.add(newFlag, cc.xyw(2, 12, 4));
256 builder.add(exactFlag, cc.xyw(2, 14, 4));
257
258 return builder.getPanel();
259 }
260
261
262
263
264
265
266 private JToolBar buildToolBar() {
267 final ToolBarBuilder bar = new ToolBarBuilder("Filter Toolbar");
268 AbstractButton button = null;
269 filterButton = ComponentFactory.createToolBarToggleButton(Actions.FILTER_APPLY_ID);
270 filterButton.putClientProperty(Resources.EDITOR_COMPONENT, this);
271 bar.add(filterButton);
272 button = ComponentFactory.createToolBarButton(Actions.FILTER_CLEAR_ID);
273 button.putClientProperty(Resources.EDITOR_COMPONENT, this);
274 bar.add(button);
275 button = ComponentFactory.createToolBarButton(Actions.FILTER_CLOSE_ID);
276 bar.add(button);
277 return bar.getToolBar();
278 }
279
280 }