1 /*
2  * aTunes
3  * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors
4  *
5  * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
6  *
7  * http://www.atunes.org
8  * http://sourceforge.net/projects/atunes
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20 
21 package net.sourceforge.atunes.kernel.modules.state;
22 
23 import java.awt.Dimension;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridLayout;
26 import java.awt.Insets;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.io.File;
30 import java.util.ArrayList;
31 import java.util.List;
32 
33 import javax.swing.JButton;
34 import javax.swing.JCheckBox;
35 import javax.swing.JComboBox;
36 import javax.swing.JLabel;
37 import javax.swing.JList;
38 import javax.swing.JPanel;
39 import javax.swing.JScrollPane;
40 import javax.swing.JTextField;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.event.ListSelectionEvent;
43 import javax.swing.event.ListSelectionListener;
44 
45 import net.sourceforge.atunes.model.IControlsBuilder;
46 import net.sourceforge.atunes.model.IDialogFactory;
47 import net.sourceforge.atunes.model.IFolderSelectorDialog;
48 import net.sourceforge.atunes.model.ILookAndFeelManager;
49 import net.sourceforge.atunes.model.IOSManager;
50 import net.sourceforge.atunes.model.IRepositoryHandler;
51 import net.sourceforge.atunes.model.IStateRepository;
52 import net.sourceforge.atunes.utils.CollectionUtils;
53 import net.sourceforge.atunes.utils.I18nUtils;
54 
55 /**
56  * The preferences panel for respository settings.
57  */
58 public final class RepositoryPanel extends AbstractPreferencesPanel {
59 
60 	private static final long serialVersionUID = 3331810461314007217L;
61 
62 	/**
63 	 * The refresh time of repository
64 	 */
65 	private JComboBox refreshTime;
66 
67 	/**
68 	 * Text field to specify command to execute before access repository
69 	 */
70 	private JTextField commandBeforeAccessRepository;
71 
72 	/**
73 	 * Text field to specify command to execute after access repository (when
74 	 * application finish)
75 	 */
76 	private JTextField commandAfterAccessRepository;
77 
78 	private JList repositoryFoldersList;
79 
80 	private IStateRepository stateRepository;
81 
82 	private ILookAndFeelManager lookAndFeelManager;
83 
84 	private IRepositoryHandler repositoryHandler;
85 
86 	private JButton addFolderButton;
87 
88 	private IDialogFactory dialogFactory;
89 
90 	private JButton removeFolderButton;
91 
92 	private List<File> repositoryFolders;
93 
94 	private IOSManager osManager;
95 
96 	private IControlsBuilder controlsBuilder;
97 
98 	private JCheckBox useRatingsStoredInTag;
99 
100 	/**
101 	 * @param controlsBuilder
102 	 */
setControlsBuilder(final IControlsBuilder controlsBuilder)103 	public void setControlsBuilder(final IControlsBuilder controlsBuilder) {
104 		this.controlsBuilder = controlsBuilder;
105 	}
106 
107 	/**
108 	 * @param osManager
109 	 */
setOsManager(final IOSManager osManager)110 	public void setOsManager(final IOSManager osManager) {
111 		this.osManager = osManager;
112 	}
113 
114 	/**
115 	 * @param dialogFactory
116 	 */
setDialogFactory(final IDialogFactory dialogFactory)117 	public void setDialogFactory(final IDialogFactory dialogFactory) {
118 		this.dialogFactory = dialogFactory;
119 	}
120 
121 	/**
122 	 * @param repositoryHandler
123 	 */
setRepositoryHandler(final IRepositoryHandler repositoryHandler)124 	public void setRepositoryHandler(final IRepositoryHandler repositoryHandler) {
125 		this.repositoryHandler = repositoryHandler;
126 	}
127 
128 	/**
129 	 * @param lookAndFeelManager
130 	 */
setLookAndFeelManager( final ILookAndFeelManager lookAndFeelManager)131 	public void setLookAndFeelManager(
132 			final ILookAndFeelManager lookAndFeelManager) {
133 		this.lookAndFeelManager = lookAndFeelManager;
134 	}
135 
136 	/**
137 	 * @param stateRepository
138 	 */
setStateRepository(final IStateRepository stateRepository)139 	public void setStateRepository(final IStateRepository stateRepository) {
140 		this.stateRepository = stateRepository;
141 	}
142 
143 	/**
144 	 * Instantiates a new repository panel.
145 	 */
RepositoryPanel()146 	public RepositoryPanel() {
147 		super(I18nUtils.getString("REPOSITORY"));
148 	}
149 
150 	/**
151 	 * Initializes panel
152 	 */
initialize()153 	public void initialize() {
154 		this.refreshTime = new JComboBox(new Integer[] { 0, 5, 10, 15, 30, 60 });
155 		this.commandBeforeAccessRepository = this.controlsBuilder
156 				.createTextField();
157 		this.commandBeforeAccessRepository.setColumns(20);
158 		this.commandAfterAccessRepository = this.controlsBuilder
159 				.createTextField();
160 		this.commandAfterAccessRepository.setColumns(20);
161 		this.repositoryFoldersList = this.lookAndFeelManager
162 				.getCurrentLookAndFeel().getList();
163 		this.repositoryFoldersList
164 				.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
165 		this.addFolderButton = new JButton(I18nUtils.getString("ADD"));
166 		this.removeFolderButton = new JButton(I18nUtils.getString("REMOVE"));
167 		this.repositoryFoldersList
168 				.addListSelectionListener(new ListSelectionListener() {
169 
170 					@Override
171 					public void valueChanged(final ListSelectionEvent event) {
172 						RepositoryPanel.this.removeFolderButton
173 								.setEnabled(RepositoryPanel.this.repositoryFoldersList
174 										.getSelectedIndex() != -1);
175 					}
176 				});
177 		this.addFolderButton.addActionListener(new ActionListener() {
178 
179 			@Override
180 			public void actionPerformed(final ActionEvent arg0) {
181 				IFolderSelectorDialog dialog = RepositoryPanel.this.dialogFactory
182 						.newDialog(IFolderSelectorDialog.class);
183 				dialog.setTitle(I18nUtils.getString("ADD_FOLDER_TO_REPOSITORY"));
184 				File folder = dialog
185 						.selectFolder(RepositoryPanel.this.osManager
186 								.getUserHome());
187 				if (folder != null) {
188 					RepositoryPanel.this.repositoryFolders.add(folder);
189 					RepositoryPanel.this.repositoryFoldersList
190 							.setListData(RepositoryPanel.this.repositoryFolders
191 									.toArray());
192 				}
193 			}
194 		});
195 		this.removeFolderButton.addActionListener(new ActionListener() {
196 
197 			@Override
198 			public void actionPerformed(final ActionEvent event) {
199 				RepositoryPanel.this.repositoryFolders
200 						.remove(RepositoryPanel.this.repositoryFoldersList
201 								.getSelectedIndex());
202 				RepositoryPanel.this.repositoryFoldersList
203 						.setListData(RepositoryPanel.this.repositoryFolders
204 								.toArray());
205 			}
206 		});
207 		this.useRatingsStoredInTag = new JCheckBox(
208 				I18nUtils.getString("USE_RATINGS_STORED_IN_TAG"));
209 		setupPanel();
210 	}
211 
212 	/**
213 	 * Add components to panel
214 	 */
setupPanel()215 	private void setupPanel() {
216 		GridBagConstraints c = new GridBagConstraints();
217 		c.gridx = 0;
218 		c.gridy = 0;
219 		c.weightx = 0;
220 		c.anchor = GridBagConstraints.WEST;
221 		c.insets = new Insets(0, 10, 0, 0);
222 		add(new JLabel(I18nUtils.getString("REPOSITORY_REFRESH_TIME")), c);
223 		c.gridx = 1;
224 		c.weightx = 1;
225 		c.insets = new Insets(0, 10, 0, 0);
226 		add(this.refreshTime, c);
227 		c.gridx = 0;
228 		c.gridy = 1;
229 		c.weightx = 1;
230 		c.insets = new Insets(10, 10, 0, 0);
231 		add(new JLabel(I18nUtils.getString("COMMAND_BEFORE_REPOSITORY_ACCESS")),
232 				c);
233 		c.gridx = 1;
234 		c.weightx = 1;
235 		add(this.commandBeforeAccessRepository, c);
236 		c.gridx = 0;
237 		c.gridy = 2;
238 		c.weightx = 0;
239 		add(new JLabel(I18nUtils.getString("COMMAND_AFTER_REPOSITORY_ACCESS")),
240 				c);
241 		c.gridx = 1;
242 		c.weightx = 1;
243 		add(this.commandAfterAccessRepository, c);
244 		c.gridx = 0;
245 		c.gridy = 3;
246 		c.insets = new Insets(20, 10, 0, 0);
247 		JScrollPane scrollPane = this.controlsBuilder
248 				.createScrollPane(this.repositoryFoldersList);
249 		scrollPane.setMinimumSize(new Dimension(400, 300));
250 		scrollPane.setPreferredSize(new Dimension(400, 300));
251 		add(scrollPane, c);
252 		JPanel addRemovePanel = new JPanel(new GridLayout(1, 2, 5, 0));
253 		addRemovePanel.add(this.addFolderButton);
254 		addRemovePanel.add(this.removeFolderButton);
255 		c.gridy = 4;
256 		c.insets = new Insets(10, 10, 0, 0);
257 		add(addRemovePanel, c);
258 		c.gridx = 0;
259 		c.gridy = 5;
260 		c.weighty = 1;
261 		c.anchor = GridBagConstraints.NORTHWEST;
262 		add(this.useRatingsStoredInTag, c);
263 	}
264 
265 	@Override
applyPreferences()266 	public boolean applyPreferences() {
267 		this.stateRepository
268 				.setAutoRepositoryRefreshTime((Integer) this.refreshTime
269 						.getSelectedItem());
270 		this.stateRepository
271 				.setCommandBeforeAccessRepository(this.commandBeforeAccessRepository
272 						.getText());
273 		this.stateRepository
274 				.setCommandAfterAccessRepository(this.commandAfterAccessRepository
275 						.getText());
276 		if (repositoryFoldersHaveChanged(this.repositoryFolders,
277 				this.repositoryHandler.getFolders())) {
278 			this.repositoryHandler.setRepositoryFolders(this.repositoryFolders);
279 		}
280 
281 		this.stateRepository.setStoreRatingInFile(this.useRatingsStoredInTag
282 				.isSelected());
283 		return false;
284 	}
285 
repositoryFoldersHaveChanged( final List<File> filesSelected, final List<File> repositoryFolders)286 	private boolean repositoryFoldersHaveChanged(
287 			final List<File> filesSelected, final List<File> repositoryFolders) {
288 		return !org.apache.commons.collections.CollectionUtils
289 				.isEqualCollection(filesSelected, repositoryFolders);
290 	}
291 
292 	/**
293 	 * Sets the refresh time.
294 	 *
295 	 * @param time
296 	 *            the new refresh time
297 	 */
setRefreshTime(final int time)298 	private void setRefreshTime(final int time) {
299 		this.refreshTime.setSelectedItem(time);
300 	}
301 
302 	/**
303 	 * Sets the command to execute before access repository
304 	 *
305 	 * @param command
306 	 */
setCommandBeforeAccessRepository(final String command)307 	private void setCommandBeforeAccessRepository(final String command) {
308 		this.commandBeforeAccessRepository.setText(command);
309 	}
310 
311 	/**
312 	 * Sets the command to execute after access repository
313 	 *
314 	 * @param command
315 	 */
setCommandAfterAccessRepository(final String command)316 	private void setCommandAfterAccessRepository(final String command) {
317 		this.commandAfterAccessRepository.setText(command);
318 	}
319 
setUseRatingsStoredInTag(final boolean storeRatingInFile)320 	private void setUseRatingsStoredInTag(final boolean storeRatingInFile) {
321 		this.useRatingsStoredInTag.setSelected(storeRatingInFile);
322 	}
323 
324 	@Override
updatePanel()325 	public void updatePanel() {
326 		setRefreshTime(this.stateRepository.getAutoRepositoryRefreshTime());
327 		setCommandBeforeAccessRepository(this.stateRepository
328 				.getCommandBeforeAccessRepository());
329 		setCommandAfterAccessRepository(this.stateRepository
330 				.getCommandAfterAccessRepository());
331 		setRepositoryFolders();
332 		setUseRatingsStoredInTag(this.stateRepository.isStoreRatingInFile());
333 	}
334 
setRepositoryFolders()335 	private void setRepositoryFolders() {
336 		this.repositoryFolders = new ArrayList<File>(
337 				this.repositoryHandler.getFolders());
338 		this.repositoryFoldersList
339 				.setListData(this.repositoryFolders.toArray());
340 		this.removeFolderButton.setEnabled(false);
341 	}
342 
343 	@Override
validatePanel()344 	public void validatePanel() throws PreferencesValidationException {
345 		if (CollectionUtils.isEmpty(this.repositoryFolders)) {
346 			throw new PreferencesValidationException(
347 					I18nUtils
348 							.getString("REPOSITORY_MUST_CONTAIN_AT_LEAST_ONE_FOLDER"),
349 					null);
350 		}
351 	}
352 
353 	@Override
dialogVisibilityChanged(final boolean visible)354 	public void dialogVisibilityChanged(final boolean visible) {
355 		// Do nothing
356 	}
357 
358 	@Override
resetImmediateChanges()359 	public void resetImmediateChanges() {
360 		// Do nothing
361 	}
362 }
363