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.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 
33 import javax.swing.ButtonGroup;
34 import javax.swing.DefaultCellEditor;
35 import javax.swing.JCheckBox;
36 import javax.swing.JComboBox;
37 import javax.swing.JLabel;
38 import javax.swing.JPanel;
39 import javax.swing.JRadioButton;
40 import javax.swing.JScrollPane;
41 import javax.swing.JTable;
42 import javax.swing.ListSelectionModel;
43 import javax.swing.SwingUtilities;
44 import javax.swing.border.TitledBorder;
45 
46 import net.sourceforge.atunes.gui.ComponentOrientationTableCellRendererCode;
47 import net.sourceforge.atunes.model.ArtistViewMode;
48 import net.sourceforge.atunes.model.IBeanFactory;
49 import net.sourceforge.atunes.model.IControlsBuilder;
50 import net.sourceforge.atunes.model.ILookAndFeelManager;
51 import net.sourceforge.atunes.model.IStateNavigation;
52 import net.sourceforge.atunes.model.IStateRepository;
53 import net.sourceforge.atunes.model.TextTagAttribute;
54 import net.sourceforge.atunes.utils.I18nUtils;
55 
56 /**
57  * Preferences of navigator
58  *
59  * @author alex
60  *
61  */
62 public final class NavigatorPanel extends AbstractPreferencesPanel {
63 
64 	private static final long serialVersionUID = -4315748284461119970L;
65 
66 	private JCheckBox showFavorites;
67 	private JCheckBox showExtendedToolTip;
68 	private JComboBox extendedToolTipDelay;
69 	private JCheckBox useSmartTagViewSorting;
70 	private JCheckBox useArtistNamesSorting;
71 	private JCheckBox useCaseSensitiveInTree;
72 	private JRadioButton useOnlyArtist;
73 	private JRadioButton useOnlyArtistOfAlbum;
74 	private JRadioButton useBothArtist;
75 
76 	/**
77 	 * Check box to highlight elements with incomplete tags (selected) or not
78 	 * (unselected)
79 	 */
80 	private JCheckBox highlightElementsWithIncompleteBasicTags;
81 
82 	/**
83 	 * Table to select which tag attributes are used to highlight incomplete tag
84 	 * folders
85 	 */
86 	private JTable highlighTagAttributesTable;
87 
88 	/**
89 	 * Scroll pane fot tag attributes
90 	 */
91 	private JScrollPane highlightTagAttributesScrollPane;
92 
93 	/**
94 	 * Table model to select tag attributes
95 	 */
96 	private TagAttributesTableModel tagAttributesTableModel;
97 
98 	private ILookAndFeelManager lookAndFeelManager;
99 
100 	private IStateRepository stateRepository;
101 
102 	private IStateNavigation stateNavigation;
103 
104 	private IBeanFactory beanFactory;
105 
106 	private IControlsBuilder controlsBuilder;
107 
108 	/**
109 	 * @param controlsBuilder
110 	 */
setControlsBuilder(final IControlsBuilder controlsBuilder)111 	public void setControlsBuilder(final IControlsBuilder controlsBuilder) {
112 		this.controlsBuilder = controlsBuilder;
113 	}
114 
115 	/**
116 	 * @param beanFactory
117 	 */
setBeanFactory(final IBeanFactory beanFactory)118 	public void setBeanFactory(final IBeanFactory beanFactory) {
119 		this.beanFactory = beanFactory;
120 	}
121 
122 	/**
123 	 * @param stateNavigation
124 	 */
setStateNavigation(final IStateNavigation stateNavigation)125 	public void setStateNavigation(final IStateNavigation stateNavigation) {
126 		this.stateNavigation = stateNavigation;
127 	}
128 
129 	/**
130 	 * @param stateRepository
131 	 */
setStateRepository(final IStateRepository stateRepository)132 	public void setStateRepository(final IStateRepository stateRepository) {
133 		this.stateRepository = stateRepository;
134 	}
135 
136 	/**
137 	 * @param lookAndFeelManager
138 	 */
setLookAndFeelManager( final ILookAndFeelManager lookAndFeelManager)139 	public void setLookAndFeelManager(
140 			final ILookAndFeelManager lookAndFeelManager) {
141 		this.lookAndFeelManager = lookAndFeelManager;
142 	}
143 
144 	/**
145 	 * Instantiates a new navigator panel.
146 	 */
NavigatorPanel()147 	public NavigatorPanel() {
148 		super(I18nUtils.getString("NAVIGATOR"));
149 	}
150 
151 	/**
152 	 * Initializes panel
153 	 */
initialize()154 	public void initialize() {
155 		this.showFavorites = new JCheckBox(
156 				I18nUtils.getString("SHOW_FAVORITES"));
157 		this.showExtendedToolTip = new JCheckBox(
158 				I18nUtils.getString("SHOW_EXTENDED_TOOLTIP"));
159 		final JLabel label = new JLabel(
160 				I18nUtils.getString("EXTENDED_TOOLTIP_DELAY"));
161 		this.extendedToolTipDelay = new JComboBox(
162 				new Integer[] { 1, 2, 3, 4, 5 });
163 		this.showExtendedToolTip.addActionListener(new ActionListener() {
164 			@Override
165 			public void actionPerformed(final ActionEvent arg0) {
166 				label.setEnabled(NavigatorPanel.this.showExtendedToolTip
167 						.isSelected());
168 				NavigatorPanel.this.extendedToolTipDelay
169 						.setEnabled(NavigatorPanel.this.showExtendedToolTip
170 								.isSelected());
171 			}
172 		});
173 		this.useSmartTagViewSorting = new JCheckBox(
174 				I18nUtils.getString("USE_SMART_TAG_VIEW_SORTING"));
175 		this.useArtistNamesSorting = new JCheckBox(
176 				I18nUtils.getString("USE_PERSON_NAMES_ARTIST_TAG_VIEW_SORTING"));
177 
178 		this.useOnlyArtist = new JRadioButton(
179 				I18nUtils.getString("ARTIST_VIEW_USE_ONLY_ARTIST"), true);
180 		this.useOnlyArtistOfAlbum = new JRadioButton(
181 				I18nUtils.getString("ARTIST_VIEW_USE_ONLY_ARTIST_OF_ALBUM"));
182 		this.useBothArtist = new JRadioButton(
183 				I18nUtils.getString("ARTIST_VIEW_USE_BOTH"));
184 
185 		ButtonGroup artistViewOptionGroup = new ButtonGroup();
186 		artistViewOptionGroup.add(this.useOnlyArtist);
187 		artistViewOptionGroup.add(this.useOnlyArtistOfAlbum);
188 		artistViewOptionGroup.add(this.useBothArtist);
189 		JPanel artistViewPanel = getArtistViewPanel();
190 
191 		this.useCaseSensitiveInTree = new JCheckBox(
192 				I18nUtils.getString("CASE_SENSITIVE_TREE"));
193 		this.highlightElementsWithIncompleteBasicTags = new JCheckBox(
194 				I18nUtils.getString("HIGHLIGHT_INCOMPLETE_TAG_ELEMENTS"));
195 		this.highlightElementsWithIncompleteBasicTags
196 				.addActionListener(new ActionListener() {
197 					@Override
198 					public void actionPerformed(final ActionEvent e) {
199 						SwingUtilities.invokeLater(new Runnable() {
200 							@Override
201 							public void run() {
202 								NavigatorPanel.this.highlightTagAttributesScrollPane
203 										.setEnabled(NavigatorPanel.this.highlightElementsWithIncompleteBasicTags
204 												.isSelected());
205 								NavigatorPanel.this.highlighTagAttributesTable
206 										.setEnabled(NavigatorPanel.this.highlightElementsWithIncompleteBasicTags
207 												.isSelected());
208 							}
209 						});
210 					}
211 				});
212 
213 		this.tagAttributesTableModel = new TagAttributesTableModel();
214 		this.highlighTagAttributesTable = getHighlighTagAttributesTable();
215 
216 		this.highlightTagAttributesScrollPane = this.controlsBuilder
217 				.createScrollPane(this.highlighTagAttributesTable);
218 		this.highlightTagAttributesScrollPane.setMinimumSize(new Dimension(300,
219 				150));
220 
221 		arrangePanel(label, artistViewPanel);
222 	}
223 
224 	/**
225 	 * @return
226 	 */
getArtistViewPanel()227 	private JPanel getArtistViewPanel() {
228 		JPanel artistViewPanel = new JPanel(new GridLayout(3, 1));
229 		artistViewPanel.setBorder(new TitledBorder(I18nUtils
230 				.getString("ARTIST")));
231 		artistViewPanel.add(this.useBothArtist);
232 		artistViewPanel.add(this.useOnlyArtist);
233 		artistViewPanel.add(this.useOnlyArtistOfAlbum);
234 		return artistViewPanel;
235 	}
236 
237 	/**
238 	 *
239 	 */
getHighlighTagAttributesTable()240 	private JTable getHighlighTagAttributesTable() {
241 		JTable table = this.lookAndFeelManager.getCurrentLookAndFeel()
242 				.getTable();
243 		table.setModel(this.tagAttributesTableModel);
244 		table.setTableHeader(null);
245 		table.getColumnModel().getColumn(0).setMaxWidth(20);
246 		table.getColumnModel().getColumn(0)
247 				.setCellEditor(new DefaultCellEditor(new JCheckBox()));
248 		table.getSelectionModel().setSelectionMode(
249 				ListSelectionModel.SINGLE_SELECTION);
250 		table.setDefaultRenderer(
251 				String.class,
252 				this.lookAndFeelManager
253 						.getCurrentLookAndFeel()
254 						.getTableCellRenderer(
255 								this.beanFactory
256 										.getBean(ComponentOrientationTableCellRendererCode.class)));
257 		return table;
258 	}
259 
260 	/**
261 	 * @param label
262 	 * @param artistViewPanel
263 	 */
arrangePanel(final JLabel label, final JPanel artistViewPanel)264 	private void arrangePanel(final JLabel label, final JPanel artistViewPanel) {
265 		GridBagConstraints c = new GridBagConstraints();
266 		c.gridx = 0;
267 		c.gridy = 0;
268 		c.weightx = 0;
269 		c.gridwidth = 1;
270 		c.anchor = GridBagConstraints.FIRST_LINE_START;
271 		add(this.showFavorites, c);
272 		c.gridy = 1;
273 		add(this.showExtendedToolTip, c);
274 		c.gridy = 2;
275 		c.insets = new Insets(0, 10, 0, 0);
276 		add(label, c);
277 		c.gridx = 1;
278 		c.weightx = 1;
279 		add(this.extendedToolTipDelay, c);
280 		c.weightx = 0;
281 		c.gridx = 0;
282 		c.gridy = 3;
283 		c.insets = new Insets(0, 0, 0, 0);
284 		c.gridwidth = 2;
285 		add(this.useSmartTagViewSorting, c);
286 		c.gridy = 4;
287 		add(this.useArtistNamesSorting, c);
288 		c.gridy = 5;
289 		add(artistViewPanel, c);
290 		c.gridy = 6;
291 		add(this.useCaseSensitiveInTree, c);
292 		c.gridy = 7;
293 		add(this.highlightElementsWithIncompleteBasicTags, c);
294 		c.gridy = 8;
295 		c.weighty = 1;
296 		c.weightx = 0;
297 		c.anchor = this.controlsBuilder.getComponentOrientation()
298 				.isLeftToRight() ? GridBagConstraints.NORTHWEST
299 				: GridBagConstraints.NORTHEAST;
300 		c.insets = new Insets(10, 20, 10, 10);
301 		add(this.highlightTagAttributesScrollPane, c);
302 	}
303 
304 	@Override
applyPreferences()305 	public boolean applyPreferences() {
306 
307 		this.stateNavigation.setShowFavoritesInNavigator(this.showFavorites
308 				.isSelected());
309 		this.stateNavigation.setShowExtendedTooltip(this.showExtendedToolTip
310 				.isSelected());
311 		this.stateNavigation
312 				.setExtendedTooltipDelay((Integer) this.extendedToolTipDelay
313 						.getSelectedItem());
314 		this.stateNavigation
315 				.setUseSmartTagViewSorting(this.useSmartTagViewSorting
316 						.isSelected());
317 		this.stateNavigation
318 				.setHighlightIncompleteTagElements(this.highlightElementsWithIncompleteBasicTags
319 						.isSelected());
320 		this.stateNavigation
321 				.setHighlightIncompleteTagFoldersAttributes(this.tagAttributesTableModel
322 						.getSelectedTagAttributes());
323 		this.stateNavigation
324 				.setUsePersonNamesArtistTagViewSorting(this.useArtistNamesSorting
325 						.isSelected());
326 		this.stateRepository
327 				.setKeyAlwaysCaseSensitiveInRepositoryStructure(this.useCaseSensitiveInTree
328 						.isSelected());
329 
330 		ArtistViewMode newArtistViewState = ArtistViewMode.BOTH;
331 		if (this.useOnlyArtist.isSelected()) {
332 			newArtistViewState = ArtistViewMode.ARTIST;
333 		} else if (this.useOnlyArtistOfAlbum.isSelected()) {
334 			newArtistViewState = ArtistViewMode.ARTIST_OF_ALBUM;
335 		} else {
336 			newArtistViewState = ArtistViewMode.BOTH;
337 		}
338 
339 		this.stateNavigation.setArtistViewMode(newArtistViewState);
340 
341 		return false;
342 	}
343 
344 	/**
345 	 * Sets the album tool tip delay.
346 	 *
347 	 * @param time
348 	 *            the new album tool tip delay
349 	 */
350 
setAlbumToolTipDelay(final int time)351 	public void setAlbumToolTipDelay(final int time) {
352 		this.extendedToolTipDelay.setSelectedItem(time);
353 	}
354 
355 	/**
356 	 * Sets the show album tool tip.
357 	 *
358 	 * @param show
359 	 *            the new show album tool tip
360 	 */
setShowAlbumToolTip(final boolean show)361 	public void setShowAlbumToolTip(final boolean show) {
362 		this.showExtendedToolTip.setSelected(show);
363 	}
364 
365 	/**
366 	 * Sets the show favorites.
367 	 *
368 	 * @param show
369 	 *            the new show favorites
370 	 */
setShowFavorites(final boolean show)371 	private void setShowFavorites(final boolean show) {
372 		this.showFavorites.setSelected(show);
373 	}
374 
375 	/**
376 	 * Sets the use smart tag view sorting.
377 	 *
378 	 * @param use
379 	 *            the new use smart tag view sorting
380 	 */
setUseSmartTagViewSorting(final boolean use)381 	private void setUseSmartTagViewSorting(final boolean use) {
382 		this.useSmartTagViewSorting.setSelected(use);
383 	}
384 
385 	/**
386 	 * Sets the use person names artist tag view sorting.
387 	 *
388 	 * @param use
389 	 *            the new se person names artist tag view sorting
390 	 */
setUsePersonNamesArtistTagViewSorting(final boolean use)391 	private void setUsePersonNamesArtistTagViewSorting(final boolean use) {
392 		this.useArtistNamesSorting.setSelected(use);
393 	}
394 
395 	/**
396 	 * Set the keys of repository structures artist and genre to case sensitive
397 	 * or not.
398 	 *
399 	 * @param value
400 	 */
setKeyAlwaysCaseSensitiveInRepositoryStructure( final boolean value)401 	private void setKeyAlwaysCaseSensitiveInRepositoryStructure(
402 			final boolean value) {
403 		this.useCaseSensitiveInTree.setSelected(value);
404 	}
405 
406 	/**
407 	 * Sets property to highlight folder with incomplete tags
408 	 *
409 	 * @param highlightFoldersWithIncompleteBasicTags
410 	 *            the highlightFoldersWithIncompleteBasicTags to set
411 	 */
setHighlightFoldersWithIncompleteBasicTags( final boolean highlightFoldersWithIncompleteBasicTags)412 	private void setHighlightFoldersWithIncompleteBasicTags(
413 			final boolean highlightFoldersWithIncompleteBasicTags) {
414 		this.highlightElementsWithIncompleteBasicTags
415 				.setSelected(highlightFoldersWithIncompleteBasicTags);
416 		this.highlightTagAttributesScrollPane
417 				.setEnabled(highlightFoldersWithIncompleteBasicTags);
418 		this.highlighTagAttributesTable
419 				.setEnabled(highlightFoldersWithIncompleteBasicTags);
420 	}
421 
422 	@Override
updatePanel()423 	public void updatePanel() {
424 		this.tagAttributesTableModel
425 				.setTagAttributes(getAllTagAttributes(this.stateNavigation
426 						.getHighlightIncompleteTagFoldersAttributes()));
427 		setShowFavorites(this.stateNavigation.isShowFavoritesInNavigator());
428 		setShowAlbumToolTip(this.stateNavigation.isShowExtendedTooltip());
429 		setAlbumToolTipDelay(this.stateNavigation.getExtendedTooltipDelay());
430 		setUseSmartTagViewSorting(this.stateNavigation
431 				.isUseSmartTagViewSorting());
432 		setHighlightFoldersWithIncompleteBasicTags(this.stateNavigation
433 				.isHighlightIncompleteTagElements());
434 		setUsePersonNamesArtistTagViewSorting(this.stateNavigation
435 				.isUsePersonNamesArtistTagViewSorting());
436 		setKeyAlwaysCaseSensitiveInRepositoryStructure(this.stateRepository
437 				.isKeyAlwaysCaseSensitiveInRepositoryStructure());
438 		setArtistViewMode(this.stateNavigation.getArtistViewMode());
439 	}
440 
441 	/**
442 	 * Returns a hash map with all tag attributes as key, and state (used or
443 	 * not) as value
444 	 *
445 	 * @param attributes
446 	 * @return
447 	 */
getAllTagAttributes( final List<TextTagAttribute> attributes)448 	private Map<TextTagAttribute, Boolean> getAllTagAttributes(
449 			final List<TextTagAttribute> attributes) {
450 		Map<TextTagAttribute, Boolean> result = new HashMap<TextTagAttribute, Boolean>();
451 		for (TextTagAttribute att : TextTagAttribute.values()) {
452 			result.put(att, false);
453 		}
454 		for (TextTagAttribute attr : attributes) {
455 			result.put(attr, true);
456 		}
457 		return result;
458 	}
459 
setArtistViewMode(final ArtistViewMode artistViewMode)460 	private void setArtistViewMode(final ArtistViewMode artistViewMode) {
461 		if (ArtistViewMode.ARTIST.equals(artistViewMode)) {
462 			this.useOnlyArtist.setSelected(true);
463 		} else if (ArtistViewMode.ARTIST_OF_ALBUM.equals(artistViewMode)) {
464 			this.useOnlyArtistOfAlbum.setSelected(true);
465 		} else {
466 			this.useBothArtist.setSelected(true);
467 		}
468 
469 	}
470 
471 	@Override
validatePanel()472 	public void validatePanel() throws PreferencesValidationException {
473 	}
474 
475 	@Override
dialogVisibilityChanged(final boolean visible)476 	public void dialogVisibilityChanged(final boolean visible) {
477 		// Do nothing
478 	}
479 
480 	@Override
resetImmediateChanges()481 	public void resetImmediateChanges() {
482 		// Do nothing
483 	}
484 
485 }
486