001 /** 002 * iFish - An iRiver iHP jukebox database creation tool 003 * 004 * Copyright (C) 2009 Richard "Shred" Körber 005 * http://ifish.shredzone.org 006 * 007 * This program is free software: you can redistribute it and/or modify 008 * it under the terms of the GNU General Public License as published by 009 * the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * This program is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 019 */ 020 package net.shredzone.ifish.gui; 021 022 import java.awt.BorderLayout; 023 import java.awt.Dimension; 024 import java.awt.event.ActionEvent; 025 import java.awt.event.KeyEvent; 026 import java.awt.event.MouseAdapter; 027 import java.awt.event.MouseEvent; 028 import java.util.prefs.Preferences; 029 030 import javax.swing.BorderFactory; 031 import javax.swing.Icon; 032 import javax.swing.JButton; 033 import javax.swing.JList; 034 import javax.swing.JOptionPane; 035 import javax.swing.JPanel; 036 import javax.swing.JScrollPane; 037 import javax.swing.JSplitPane; 038 import javax.swing.JTable; 039 import javax.swing.JToolBar; 040 import javax.swing.KeyStroke; 041 import javax.swing.ListSelectionModel; 042 import javax.swing.event.ListSelectionEvent; 043 import javax.swing.event.ListSelectionListener; 044 045 import net.shredzone.ifish.IFishPane; 046 import net.shredzone.ifish.IFishPrefs; 047 import net.shredzone.ifish.PlaylistSource; 048 import net.shredzone.ifish.actions.IFishAction; 049 import net.shredzone.ifish.db.Entry; 050 import net.shredzone.ifish.db.Playlist; 051 import net.shredzone.ifish.db.PlaylistDb; 052 import net.shredzone.ifish.i18n.L; 053 import net.shredzone.ifish.pool.ImgPool; 054 import net.shredzone.jshred.swing.JToolbarButton; 055 import net.shredzone.jshred.swing.SwingUtils; 056 057 /** 058 * This panel allows to see the playlists. 059 * 060 * @author Richard Körber <dev@shredzone.de> 061 * @version $Id: PlaylistPane.java 291 2009-04-28 21:29:27Z shred $ 062 */ 063 public class PlaylistPane extends JPanel implements PlaylistSource, ListSelectionListener { 064 private static final long serialVersionUID = 3834587690816844855L; 065 066 private final IFishPane fish; 067 private final IFishPrefs prefs; 068 protected final MoveAction actionTop, actionUp, actionDown, actionBottom; 069 protected final SortAction actionAsc, actionDesc, actionShuffle; 070 protected final AllAction actionAll; 071 protected final PasteAction actionPaste; 072 protected final RemoveAction actionRemove; 073 protected final CreateAction actionPLCreate; 074 protected final RenameAction actionPLRename; 075 protected final DeleteAction actionPLDelete; 076 077 private JList jlDirectory; 078 private JTable jtPlaylist; 079 private JToolBar jTools; 080 private JToolBar jPLTools; 081 private Playlist pl; 082 private JButton jbCreate; 083 private JButton jbRename; 084 085 /** 086 * Create a PlaylistPane. 087 * 088 * @param fish Reference to IFishPane 089 */ 090 public PlaylistPane( IFishPane fish ) { 091 this.fish = fish; 092 this.prefs = fish.getPrefs(); 093 094 //--- Left: the playlist list --- 095 setLayout( new BorderLayout() ); 096 097 JSplitPane jSplit = new JSplitPane(); 098 jSplit.setContinuousLayout( true ); 099 jSplit.setBorder( null ); 100 jSplit.setDividerSize( 3 ); 101 add( jSplit, BorderLayout.CENTER ); 102 103 JPanel jpLeft = new JPanel( new BorderLayout() ); 104 { 105 jlDirectory = new JList(); 106 jlDirectory.setCellRenderer( new PlaylistCellRenderer() ); 107 jlDirectory.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 108 jlDirectory.addListSelectionListener( this ); 109 110 jpLeft.add( new JScrollPane( jlDirectory ), BorderLayout.CENTER ); 111 112 jPLTools = new JToolBar( L.tr("pl.pltoolbar") ); 113 jPLTools.setFloatable( false ); 114 jPLTools.setRollover( true ); 115 jpLeft.add( jPLTools, BorderLayout.NORTH ); 116 } 117 jpLeft.setMinimumSize( new Dimension( 150, jpLeft.getMinimumSize().height ) ); 118 jpLeft.setPreferredSize( new Dimension( 150, jpLeft.getPreferredSize().height ) ); 119 jSplit.setLeftComponent( jpLeft ); 120 121 //--- Right: the playlist entries --- 122 JPanel jpRight = new JPanel( new BorderLayout() ); 123 { 124 jtPlaylist = new JTable(); 125 jtPlaylist.setAutoResizeMode( JTable.AUTO_RESIZE_OFF ); 126 jtPlaylist.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION ); 127 jtPlaylist.getSelectionModel().addListSelectionListener( this ); 128 jtPlaylist.setTransferHandler( new EntryTransferHandler( fish ) ); 129 jtPlaylist.setDragEnabled( true ); 130 131 jpRight.add( new JScrollPane( jtPlaylist ), BorderLayout.CENTER ); 132 133 jTools = new JToolBar( L.tr("pl.toolbar") ); 134 jTools.setFloatable( false ); 135 jTools.setRollover( true ); 136 jpRight.add( jTools, BorderLayout.NORTH ); 137 } 138 jSplit.setRightComponent( jpRight ); 139 140 //--- React on double clicks --- 141 jtPlaylist.addMouseListener( new MouseAdapter() { 142 @Override 143 public void mouseClicked( MouseEvent e ) { 144 if( e.getClickCount()==2 ) { 145 IFishAction action = PlaylistPane.this.fish.getAction( IFishPane.ACTION_PLAYER_PLAY ); 146 if( action.isEnabled() ) { 147 action.perform(); 148 } 149 } 150 } 151 }); 152 153 //--- Create actions --- 154 actionTop = new MoveAction( this, fish, L.tr("pl.action.top") , ImgPool.get("pl_top.png") , L.tr("pl.action.top.tt"), MoveAction.MODE_TOP ); 155 actionUp = new MoveAction( this, fish, L.tr("pl.action.up") , ImgPool.get("pl_up.png") , L.tr("pl.action.up.tt"), MoveAction.MODE_UP ); 156 actionDown = new MoveAction( this, fish, L.tr("pl.action.down") , ImgPool.get("pl_down.png") , L.tr("pl.action.down.tt"), MoveAction.MODE_DOWN ); 157 actionBottom = new MoveAction( this, fish, L.tr("pl.action.bottom") , ImgPool.get("pl_bottom.png") , L.tr("pl.action.bottom.tt"), MoveAction.MODE_BOTTOM ); 158 actionAsc = new SortAction( this, fish, L.tr("pl.action.asc") , ImgPool.get("pl_asc.png") , L.tr("pl.action.asc.tt"), SortAction.MODE_ASC ); 159 actionDesc = new SortAction( this, fish, L.tr("pl.action.desc") , ImgPool.get("pl_desc.png") , L.tr("pl.action.desc.tt"), SortAction.MODE_DESC ); 160 actionShuffle = new SortAction( this, fish, L.tr("pl.action.shuffle"), ImgPool.get("pl_shuffle.png"), L.tr("pl.action.shuffle.tt"), SortAction.MODE_SHUFFLE ); 161 actionAll = new AllAction( this, fish, L.tr("pl.action.all") , ImgPool.get("pl_all.png") , L.tr("pl.action.all.tt") ); 162 actionPaste = new PasteAction( this, fish, L.tr("pl.action.paste") , ImgPool.get("pl_paste.png") , L.tr("pl.action.paste.tt") ); 163 actionRemove = new RemoveAction( this, fish, L.tr("pl.action.remove") , ImgPool.get("pl_remove.png") , L.tr("pl.action.remove.tt") ); 164 actionPLCreate = new CreateAction( this, fish, L.tr("pl.action.create") , ImgPool.get("pl_add.png") , L.tr("pl.action.create.tt") ); 165 actionPLRename = new RenameAction( this, fish, L.tr("pl.action.rename") , ImgPool.get("pl_rename.png") , L.tr("pl.action.rename.tt") ); 166 actionPLDelete = new DeleteAction( this, fish, L.tr("pl.action.delete") , ImgPool.get("pl_remove.png") , L.tr("pl.action.delete.tt") ); 167 168 //--- Add buttons to Toolbar --- 169 jTools.add( new JToolbarButton( actionTop ) ); 170 jTools.add( new JToolbarButton( actionUp ) ); 171 jTools.add( new JToolbarButton( actionDown ) ); 172 jTools.add( new JToolbarButton( actionBottom ) ); 173 jTools.addSeparator(); 174 jTools.add( new JToolbarButton( actionAsc ) ); 175 jTools.add( new JToolbarButton( actionDesc ) ); 176 jTools.add( new JToolbarButton( actionShuffle ) ); 177 jTools.addSeparator(); 178 jTools.add( new JToolbarButton( actionAll ) ); 179 jTools.addSeparator(); 180 jTools.add( new JToolbarButton( actionPaste ) ); 181 jTools.add( new JToolbarButton( actionRemove ) ); 182 183 //--- Add buttons to Playlist Toolbar --- 184 jPLTools.add( jbCreate = new JToolbarButton( actionPLCreate ) ); 185 jPLTools.add( jbRename = new JToolbarButton( actionPLRename ) ); 186 jPLTools.add( new JToolbarButton( actionPLDelete ) ); 187 } 188 189 /** 190 * Set a playlist database. Its contents will be shown in the playlist 191 * list on the left. 192 * 193 * @param playlist New PlaylistDb 194 */ 195 public void setPlaylistDb( PlaylistDb playlist ) { 196 if( playlist!=null ) { 197 jlDirectory.setModel( playlist ); 198 clearPlaylist(); 199 } 200 } 201 202 /** 203 * Internal ListSelectionListener implementation, do not use. 204 * 205 * @param e ListSelectionEvent 206 */ 207 @Override 208 public void valueChanged( ListSelectionEvent e ) { 209 Object src = e.getSource(); 210 211 if( src.equals( jlDirectory ) ) { 212 Playlist pl = (Playlist) jlDirectory.getSelectedValue(); 213 if( pl!=null ) { 214 setPlaylist( pl ); 215 }else { 216 clearPlaylist(); 217 } 218 } 219 220 fish.setPlaylistSource( this ); 221 } 222 223 /** 224 * Set a selected playlist, showing it in the contents table. 225 * 226 * @param pl Playlist to be shown. 227 */ 228 protected void setPlaylist( Playlist pl ) { 229 this.pl = pl; 230 jtPlaylist.setModel( new PlaylistTableModel( pl ) ); 231 SwingUtils.spreadColumns( jtPlaylist, 300 ); 232 } 233 234 /** 235 * Clear the playlist contents, setting an empty list. 236 */ 237 protected void clearPlaylist() { 238 setPlaylist( new Playlist("empty") ); 239 } 240 241 /** 242 * Get an array of all Entry to be played. 243 * 244 * @return Array of Entry, might be empty. 245 */ 246 @Override 247 public Entry[] getSelectedEntries() { 248 int[] rows = jtPlaylist.getSelectedRows(); 249 if( rows.length>=0 ) { 250 Entry[] result = new Entry[rows.length]; 251 for( int ix=0; ix<rows.length; ix++ ) { 252 result[ix] = (Entry) pl.getElementAt( rows[ix] ); 253 } 254 return result; 255 }else { 256 return new Entry[0]; 257 } 258 } 259 260 protected static boolean isValid( String name ) { 261 if( name==null || name.length()==0 || name.length()>50 ) return false; 262 for( int ix=0; ix<name.length(); ix++ ) { 263 char ch = name.charAt(ix); 264 if( ch=='\\' || ch=='/' || ch=='.' ) return false; 265 if( Character.isISOControl(ch) ) return false; 266 } 267 return true; 268 } 269 270 271 /*----------------------------------------------------------------------------*/ 272 273 public static class MoveAction extends IFishAction implements ListSelectionListener { 274 private static final long serialVersionUID = 3761968259188144435L; 275 public final static int MODE_TOP = 0; 276 public final static int MODE_UP = 1; 277 public final static int MODE_DOWN = 2; 278 public final static int MODE_BOTTOM = 3; 279 private final static KeyStroke STROKES[] = new KeyStroke[] { 280 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD9, 0 ), 281 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD8, 0 ), 282 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD2, 0 ), 283 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD3, 0 ), 284 }; 285 private final PlaylistPane pl; 286 private final int mode; 287 288 public MoveAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip, int mode ) { 289 super( fish, name, icon, tip, STROKES[mode] ); 290 this.pl = pl; 291 this.mode = mode; 292 pl.jtPlaylist.getSelectionModel().addListSelectionListener( this ); 293 updateState(); 294 } 295 296 @Override 297 protected void action() { 298 int pos = pl.jtPlaylist.getSelectedRow(); 299 Entry entry = (Entry) pl.pl.getElementAt( pos ); 300 switch( mode ) { 301 case MODE_TOP: pos=0; break; 302 case MODE_UP: pos--; break; 303 case MODE_DOWN: pos+=2; break; 304 case MODE_BOTTOM: pos=pl.pl.getSize(); break; 305 } 306 pl.pl.insertEntry( pos, entry ); 307 fish.setUnsaved( true ); 308 if( mode==MODE_DOWN || mode==MODE_BOTTOM ) 309 pos--; 310 pl.jtPlaylist.setRowSelectionInterval( pos,pos ); 311 } 312 313 @Override 314 public void valueChanged( ListSelectionEvent e ) { 315 updateState(); 316 } 317 318 protected void updateState() { 319 //--- Exactly one row selected? --- 320 if( pl.jtPlaylist.getSelectedRowCount() != 1 ) { 321 setEnabled( false ); 322 return; 323 } 324 325 //--- Don't shift past the top --- 326 int row = pl.jtPlaylist.getSelectedRow(); 327 if( row==0 && ( mode==MODE_TOP || mode==MODE_UP ) ) { 328 setEnabled( false ); 329 return; 330 } 331 332 //--- Don't shift past the bottom --- 333 if( row==pl.jtPlaylist.getRowCount()-1 && ( mode==MODE_BOTTOM || mode==MODE_DOWN ) ) { 334 setEnabled( false ); 335 return; 336 } 337 338 setEnabled( true ); 339 } 340 } 341 342 /*----------------------------------------------------------------------------*/ 343 344 public static class SortAction extends IFishAction implements ListSelectionListener { 345 private static final long serialVersionUID = 3257288023992777015L; 346 public final static int MODE_ASC = 0; 347 public final static int MODE_DESC = 1; 348 public final static int MODE_SHUFFLE = 2; 349 private final static KeyStroke STROKES[] = new KeyStroke[] { 350 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD1, 0 ), 351 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD7, 0 ), 352 KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD4, 0 ), 353 }; 354 private final PlaylistPane pl; 355 private final int mode; 356 357 public SortAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip, int mode ) { 358 super( fish, name, icon, tip, STROKES[mode] ); 359 this.pl = pl; 360 this.mode = mode; 361 pl.jtPlaylist.getSelectionModel().addListSelectionListener( this ); 362 updateState(); 363 } 364 365 @Override 366 protected void action() { 367 int[] rows = pl.jtPlaylist.getSelectedRows(); 368 if( mode!=MODE_SHUFFLE ) { 369 pl.pl.sort( rows[0], rows[rows.length-1]+1, (mode==MODE_DESC) ); 370 }else { 371 pl.pl.shuffle( rows[0], rows[rows.length-1]+1 ); 372 } 373 fish.setUnsaved( true ); 374 } 375 376 @Override 377 public void valueChanged( ListSelectionEvent e ) { 378 updateState(); 379 } 380 381 protected void updateState() { 382 int[] rows = pl.jtPlaylist.getSelectedRows(); 383 384 //--- At least one entry selected? --- 385 if( rows.length<=1 ) { 386 setEnabled(false); 387 return; 388 } 389 390 //--- Continuous selection? --- 391 int start = rows[0]; 392 for( int ix=1; ix<rows.length; ix++ ) { 393 start++; 394 if( start!=rows[ix] ) { 395 setEnabled(false); 396 return; 397 } 398 } 399 400 //--- Then sorting is allowed --- 401 setEnabled(true); 402 } 403 } 404 405 /*----------------------------------------------------------------------------*/ 406 407 public static class AllAction extends IFishAction { 408 private static final long serialVersionUID = 3978426940145414455L; 409 private final PlaylistPane pl; 410 411 public AllAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 412 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_A, ActionEvent.CTRL_MASK ) ); 413 this.pl = pl; 414 } 415 416 @Override 417 protected void action() { 418 pl.jtPlaylist.selectAll(); 419 } 420 } 421 422 /*----------------------------------------------------------------------------*/ 423 424 public static class PasteAction extends IFishAction implements ListSelectionListener { 425 private static final long serialVersionUID = 3256723974544306227L; 426 private final PlaylistPane pl; 427 428 public PasteAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 429 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_V, ActionEvent.CTRL_MASK ) ); 430 this.pl = pl; 431 pl.jlDirectory.getSelectionModel().addListSelectionListener( this ); 432 updateState(); 433 } 434 435 @Override 436 protected void action() { 437 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 438 if( selection!=null && selection.isStatic() ) { 439 Entry[] entries = fish.getSelectedDatabaseEntries(); 440 if( entries.length>0 ) { 441 for( int ix=0; ix<entries.length; ix++ ) { 442 Entry entry = entries[ix]; 443 if(! selection.contains(entry) ) { 444 selection.addEntry( entry ); 445 } 446 } 447 fish.setUnsaved( true ); 448 SwingUtils.spreadColumns( pl.jtPlaylist, 300 ); 449 } 450 } 451 } 452 453 @Override 454 public void valueChanged( ListSelectionEvent e ) { 455 updateState(); 456 } 457 458 protected void updateState() { 459 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 460 if( selection!=null && selection.isStatic() ) { 461 setEnabled( true ); 462 return; 463 } 464 setEnabled( false ); 465 } 466 } 467 468 /*----------------------------------------------------------------------------*/ 469 470 public static class RemoveAction extends IFishAction implements ListSelectionListener { 471 private static final long serialVersionUID = 3257003276250984498L; 472 private final PlaylistPane pl; 473 474 public RemoveAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 475 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_DELETE, 0 ) ); 476 this.pl = pl; 477 pl.jlDirectory.getSelectionModel().addListSelectionListener( this ); 478 pl.jtPlaylist.getSelectionModel().addListSelectionListener( this ); 479 updateState(); 480 } 481 482 @Override 483 protected void action() { 484 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 485 if( selection!=null && selection.isStatic() ) { 486 int[] rows = pl.jtPlaylist.getSelectedRows(); 487 for( int ix=rows.length-1; ix>=0; ix-- ) { 488 Entry entry = (Entry) pl.pl.getElementAt( rows[ix] ); 489 pl.pl.removeEntry( entry ); 490 } 491 fish.setUnsaved( true ); 492 } 493 } 494 495 @Override 496 public void valueChanged( ListSelectionEvent e ) { 497 updateState(); 498 } 499 500 protected void updateState() { 501 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 502 if( selection!=null && selection.isStatic() ) { 503 if( pl.jtPlaylist.getSelectedRowCount() > 0 ) { 504 setEnabled( true ); 505 return; 506 } 507 } 508 setEnabled( false ); 509 } 510 } 511 512 /*----------------------------------------------------------------------------*/ 513 514 public static class CreateAction extends IFishAction { 515 private static final long serialVersionUID = 3256720671680771892L; 516 private final PlaylistPane pl; 517 518 public CreateAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 519 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_N, ActionEvent.CTRL_MASK ) ); 520 this.pl = pl; 521 } 522 523 @Override 524 protected void action() { 525 String name = JOptionPane.showInputDialog( 526 pl.jbCreate, 527 L.tr("pl.create.name"), 528 L.tr("pl.create.title"), 529 JOptionPane.QUESTION_MESSAGE 530 ); 531 if( name!=null && isValid(name) ) { 532 PlaylistDb pldb = fish.getPlaylist(); 533 boolean contained = pldb.containsPlaylist( name ); 534 Playlist newPL = fish.getPlaylist().getPlaylist( name ); 535 if( !contained ) { 536 newPL.setStatic( true ); 537 newPL.setCustomer( true ); 538 fish.setUnsaved( true ); 539 } 540 pl.jlDirectory.setSelectedValue( newPL, true ); 541 } 542 } 543 } 544 545 /*----------------------------------------------------------------------------*/ 546 547 public static class RenameAction extends IFishAction implements ListSelectionListener { 548 private static final long serialVersionUID = 3257847692691845175L; 549 private final PlaylistPane pl; 550 551 public RenameAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 552 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_F2, 0 ) ); 553 this.pl = pl; 554 pl.jlDirectory.getSelectionModel().addListSelectionListener( this ); 555 updateState(); 556 } 557 558 @Override 559 protected void action() { 560 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 561 if( selection!=null ) { 562 if( selection.isStatic() ) { 563 Object input = JOptionPane.showInputDialog( 564 pl.jbRename, 565 L.tr("pl.rename.name"), 566 L.tr("pl.rename.title"), 567 JOptionPane.QUESTION_MESSAGE, 568 null, 569 null, 570 selection.getName() 571 ); 572 if( input!=null ) { 573 String name = input.toString(); 574 if( isValid(name) && !name.equals( selection.getName() ) ) { 575 PlaylistDb model = (PlaylistDb) pl.jlDirectory.getModel(); 576 if(! model.containsPlaylist( name ) ) { 577 model.renamePlaylist( selection, name ); 578 pl.clearPlaylist(); 579 pl.jlDirectory.setSelectedValue( selection, true ); 580 fish.setUnsaved( true ); 581 }else { 582 JOptionPane.showMessageDialog( 583 pl.jbRename, 584 L.tr("pl.rename.exists"), 585 L.tr("pl.rename.title"), 586 JOptionPane.ERROR_MESSAGE 587 ); 588 } 589 } 590 } 591 } 592 } 593 } 594 595 @Override 596 public void valueChanged( ListSelectionEvent e ) { 597 updateState(); 598 } 599 600 protected void updateState() { 601 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 602 if( selection!=null ) { 603 if( selection.isStatic() ) { 604 setEnabled( true ); 605 return; 606 } 607 } 608 setEnabled( false ); 609 } 610 } 611 612 /*----------------------------------------------------------------------------*/ 613 614 public static class DeleteAction extends IFishAction implements ListSelectionListener { 615 private static final long serialVersionUID = 3257004358649722418L; 616 private final PlaylistPane pl; 617 618 public DeleteAction( PlaylistPane pl, IFishPane fish, String name, Icon icon, String tip ) { 619 super( fish, name, icon, tip, KeyStroke.getKeyStroke( KeyEvent.VK_DELETE, ActionEvent.SHIFT_MASK ) ); 620 this.pl = pl; 621 pl.jlDirectory.getSelectionModel().addListSelectionListener( this ); 622 updateState(); 623 } 624 625 @Override 626 protected void action() { 627 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 628 if( selection!=null ) { 629 if( selection.isStatic() ) { 630 PlaylistDb model = (PlaylistDb) pl.jlDirectory.getModel(); 631 model.removePlaylist( selection ); 632 pl.clearPlaylist(); 633 fish.setUnsaved( true ); 634 } 635 } 636 } 637 638 @Override 639 public void valueChanged( ListSelectionEvent e ) { 640 updateState(); 641 } 642 643 protected void updateState() { 644 Playlist selection = (Playlist) pl.jlDirectory.getSelectedValue(); 645 if( selection!=null ) { 646 if( selection.isStatic() ) { 647 setEnabled( true ); 648 return; 649 } 650 } 651 setEnabled( false ); 652 } 653 } 654 655 }