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