From c1d9ae553f55d12a8c2cee32c93821afa4c88d21 Mon Sep 17 00:00:00 2001 From: firewyre Date: Sat, 1 Aug 2015 23:33:37 +0000 Subject: [PATCH] Added missing tooltips to main window, save as dialog's file filter defaults to the currently loaded file's type, disabled playlist editing other than reordering for iTunes playlists (MVP), added support for setting the dialog Message to ProgressDialog, and added iTunes URL support. --- src/listfix/controller/GUIDriver.java | 5 +- .../io/readers/playlists/ITunesXMLReader.java | 15 ++++- .../io/writers/playlists/ITunesXMLWriter.java | 3 +- .../playlists/itunes/ITunesMediaLibrary.java | 5 +- .../playlists/itunes/ITunesPlaylistEntry.java | 16 +++-- .../model/playlists/itunes/ITunesTrack.java | 10 ++- src/listfix/view/GUIScreen.form | 12 ++-- src/listfix/view/GUIScreen.java | 62 +++++++++++++++---- .../view/controls/PlaylistEditCtrl.java | 24 ++++--- src/listfix/view/dialogs/ProgressDialog.java | 5 ++ 10 files changed, 111 insertions(+), 46 deletions(-) diff --git a/src/listfix/controller/GUIDriver.java b/src/listfix/controller/GUIDriver.java index 11c932d7..4db91d96 100644 --- a/src/listfix/controller/GUIDriver.java +++ b/src/listfix/controller/GUIDriver.java @@ -21,24 +21,21 @@ package listfix.controller; import java.io.File; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; import listfix.exceptions.MediaDirNotFoundException; - import listfix.io.writers.FileWriter; import listfix.io.IniFileConverter; import listfix.io.readers.IniFileReader; import listfix.io.readers.OptionsReader; import listfix.io.UNCFile; - import listfix.model.AppOptions; import listfix.model.PlaylistHistory; - import listfix.util.ArrayFunctions; import listfix.util.ExStack; + import org.apache.log4j.Logger; /** diff --git a/src/listfix/io/readers/playlists/ITunesXMLReader.java b/src/listfix/io/readers/playlists/ITunesXMLReader.java index 8d82095e..f7446c65 100644 --- a/src/listfix/io/readers/playlists/ITunesXMLReader.java +++ b/src/listfix/io/readers/playlists/ITunesXMLReader.java @@ -132,9 +132,18 @@ private PlaylistEntry iTunesTrackToPlaylistEntry(ITunesTrack track) { try { - ITunesPlaylistEntry result = new ITunesPlaylistEntry(new File((new URI(track.getLocation())).getPath()), track.getArtist() + " - " + track.getName(), track.getDuration(), _listFile, track); - // result.setTrackId(track.getTrackId()); - return result; + if (track.getTrackType().equals(ITunesTrack.URL)) + { + ITunesPlaylistEntry result = new ITunesPlaylistEntry(new URI(track.getLocation()), track); + // result.setTrackId(track.getTrackId()); + return result; + } + else + { + ITunesPlaylistEntry result = new ITunesPlaylistEntry(new File((new URI(track.getLocation())).getPath()), track.getArtist() + " - " + track.getName(), track.getDuration(), _listFile, track); + // result.setTrackId(track.getTrackId()); + return result; + } } catch (URISyntaxException ex) { diff --git a/src/listfix/io/writers/playlists/ITunesXMLWriter.java b/src/listfix/io/writers/playlists/ITunesXMLWriter.java index d4ac287e..d43c80ee 100644 --- a/src/listfix/io/writers/playlists/ITunesXMLWriter.java +++ b/src/listfix/io/writers/playlists/ITunesXMLWriter.java @@ -59,7 +59,7 @@ public void save(Playlist list, boolean saveRelative, ProgressAdapter adapter) t { Map trackMap = new HashMap<>(); - // Need to take each entry in the playlist and update the Dict in its corresponding ITunesTrack + // Need to take each entry in the playlist and update the Dict in its corresponding ITunesTrack to point to the proper location // Add each ITunesTrack to a map ITunesTrack tempTrack; for (PlaylistEntry entry : list.getEntries()) @@ -91,6 +91,7 @@ public void save(Playlist list, boolean saveRelative, ProgressAdapter adapter) t } ITunesPlaylist iList = (ITunesPlaylist)list; + iList.getLibrary().setTracks(trackMap); if (!adapter.getCancelled()) { diff --git a/src/listfix/model/playlists/itunes/ITunesMediaLibrary.java b/src/listfix/model/playlists/itunes/ITunesMediaLibrary.java index 58e91024..f91512a5 100644 --- a/src/listfix/model/playlists/itunes/ITunesMediaLibrary.java +++ b/src/listfix/model/playlists/itunes/ITunesMediaLibrary.java @@ -24,6 +24,7 @@ import christophedelory.plist.Array; import christophedelory.plist.Dict; import christophedelory.plist.Integer; +import christophedelory.plist.Key; import christophedelory.plist.PlistObject; import java.util.ArrayList; @@ -80,9 +81,8 @@ public Map getTracks() result.put(key.getValue(), track); } return result; - } + } - /** public void setTracks(Map trackMap) { Dict rootDict = ((Dict)_plist.getPlist().getPlistObject()); @@ -96,7 +96,6 @@ public void setTracks(Map trackMap) tracksDictionary.put(plistKey, trackMap.get(key).getTrackDict()); } } - */ /** * Gets the Playlists section of an iTunes library/playlist file as a list of ITunesTrackList objects. diff --git a/src/listfix/model/playlists/itunes/ITunesPlaylistEntry.java b/src/listfix/model/playlists/itunes/ITunesPlaylistEntry.java index 3ebf086f..3e5ab46f 100644 --- a/src/listfix/model/playlists/itunes/ITunesPlaylistEntry.java +++ b/src/listfix/model/playlists/itunes/ITunesPlaylistEntry.java @@ -21,7 +21,10 @@ package listfix.model.playlists.itunes; import java.io.File; +import java.net.URI; + import listfix.model.playlists.PlaylistEntry; + import org.apache.log4j.Logger; /** @@ -40,6 +43,12 @@ public ITunesPlaylistEntry(File input, String title, long length, File list, ITu super(input, title, length, list); _track = track; } + + public ITunesPlaylistEntry(URI input, ITunesTrack track) + { + super(input, ""); + _track = track; + } private ITunesPlaylistEntry(ITunesPlaylistEntry toClone) { @@ -62,11 +71,6 @@ public ITunesTrack getTrack() @Override public Object clone() { - ITunesPlaylistEntry result = null; - if (!this.isURL()) - { - result = new ITunesPlaylistEntry(this); - } - return result; + return new ITunesPlaylistEntry(this); } } diff --git a/src/listfix/model/playlists/itunes/ITunesTrack.java b/src/listfix/model/playlists/itunes/ITunesTrack.java index dff2fd2f..c1edcc00 100644 --- a/src/listfix/model/playlists/itunes/ITunesTrack.java +++ b/src/listfix/model/playlists/itunes/ITunesTrack.java @@ -31,7 +31,10 @@ */ public class ITunesTrack { - private Dict _trackDict; + private final Dict _trackDict; + + public static final String FILE = "File"; + public static final String URL = "URL"; /** * Constructor that takes a christophedelory.plist.Dict object. @@ -86,6 +89,11 @@ public String getAlbumArtist() { return DictionaryParser.getKeyValueAsString(_trackDict, "Album Artist"); } + + public String getTrackType() + { + return DictionaryParser.getKeyValueAsString(_trackDict, "Track Type"); + } /** * @return the _duration diff --git a/src/listfix/view/GUIScreen.form b/src/listfix/view/GUIScreen.form index e3dd14ca..da5870c2 100644 --- a/src/listfix/view/GUIScreen.form +++ b/src/listfix/view/GUIScreen.form @@ -43,8 +43,8 @@ - - + + @@ -171,7 +171,7 @@ - + @@ -237,7 +237,7 @@ - + @@ -564,7 +564,7 @@ - + @@ -702,7 +702,7 @@ - + diff --git a/src/listfix/view/GUIScreen.java b/src/listfix/view/GUIScreen.java index dc3c6d75..407ab379 100644 --- a/src/listfix/view/GUIScreen.java +++ b/src/listfix/view/GUIScreen.java @@ -89,6 +89,7 @@ import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; +import javax.swing.filechooser.FileFilter; import javax.swing.plaf.FontUIResource; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; @@ -844,8 +845,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) _playlistTreeRightClickMenu.add(_miClosestMatchesSearch); _miDeletePlaylist.setMnemonic('D'); - _miDeletePlaylist.setText("Delete Select Playlists"); - _miDeletePlaylist.setToolTipText("Delete Select Playlists"); + _miDeletePlaylist.setText("Delete Selected"); + _miDeletePlaylist.setToolTipText("Delete Selected Folders & Playlists"); _miDeletePlaylist.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) @@ -946,7 +947,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) _mediaLibraryButtonPanel.add(_removeMediaDirButton); _refreshMediaDirsButton.setText("Refresh"); - _refreshMediaDirsButton.setToolTipText("The contents of your media library are cached, refresh to pickup changes"); + _refreshMediaDirsButton.setToolTipText("The contents of your media library are cached; refresh to pickup changes"); _refreshMediaDirsButton.setFocusable(false); _refreshMediaDirsButton.setMargin(new java.awt.Insets(2, 8, 2, 8)); _refreshMediaDirsButton.setMinimumSize(new java.awt.Dimension(71, 25)); @@ -1002,7 +1003,7 @@ public void keyPressed(java.awt.event.KeyEvent evt) _playlistsDirectoryButtonPanel.setName(""); // NOI18N _btnSetPlaylistsDir.setText("Set"); - _btnSetPlaylistsDir.setToolTipText("Choose a folder (recursively searched for playlists to be shown here)"); + _btnSetPlaylistsDir.setToolTipText("Opens the options screen where you can set your playlists directory "); _btnSetPlaylistsDir.setMargin(new java.awt.Insets(2, 8, 2, 8)); _btnSetPlaylistsDir.addActionListener(new java.awt.event.ActionListener() { @@ -1225,7 +1226,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) _saveAllMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK)); _saveAllMenuItem.setMnemonic('S'); _saveAllMenuItem.setText("Save All"); - _saveAllMenuItem.setToolTipText(""); + _saveAllMenuItem.setToolTipText("Save All Open Playlists"); _saveAllMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) @@ -1284,7 +1285,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) _appOptionsMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.ALT_MASK)); _appOptionsMenuItem.setMnemonic('p'); _appOptionsMenuItem.setText("Options..."); - _appOptionsMenuItem.setToolTipText(""); + _appOptionsMenuItem.setToolTipText("Opens the Options Screen"); _appOptionsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) @@ -1626,7 +1627,7 @@ private void _saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN return; } - handleSavePlaylistAs(_currentPlaylist); + handleSaveAs(_currentPlaylist); }//GEN-LAST:event__saveAsMenuItemActionPerformed private void openIconButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_openIconButtonActionPerformed @@ -1984,7 +1985,7 @@ private void handlePlaylistSave(final Playlist list) throws HeadlessException { if (list.isNew()) { - handleSavePlaylistAs(list); + handleSaveAs(list); } else { @@ -2001,7 +2002,8 @@ protected Void doInBackground() throws Exception return null; } }; - ProgressDialog pd = new ProgressDialog(this, true, worker, "Saving...", false, false); + ProgressDialog pd = new ProgressDialog(this, true, worker, "Saving...", list.getType() == PlaylistType.ITUNES || list.getType() == PlaylistType.XSPF, false); + pd.setMessage("Please wait while your playlist is saved to disk."); pd.setVisible(true); worker.get(); } @@ -2015,11 +2017,39 @@ protected Void doInBackground() throws Exception setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } + } + + private FileFilter getFileFilterForPlaylist(Playlist list) + { + switch(list.getType()) + { + case ITUNES: + return new ExtensionFilter("xml", "iTunes Playlist (*.xml)"); + case M3U: + if (list.isUtfFormat() || list.getFile().getPath().endsWith("8")) + { + return new ExtensionFilter("m3u8", "M3U8 Playlist (*.m3u8)"); + } + else + { + return new ExtensionFilter("m3u", "M3U Playlist (*.m3u)"); + } + case PLS: + return new ExtensionFilter("pls", "PLS Playlist (*.pls)"); + case WPL: + return new ExtensionFilter("wpl", "WPL Playlist (*.wpl)"); + case XSPF: + return new ExtensionFilter("xspf", "XSPF Playlist (*.xspf)"); + case UNKNOWN: + return new ExtensionFilter("m3u8", "M3U8 Playlist (*.m3u8)"); + } + return new ExtensionFilter("m3u8", "M3U8 Playlist (*.m3u8)"); } - private boolean handleSavePlaylistAs(Playlist list) + private boolean handleSaveAs(Playlist list) { _jSaveFileChooser.setSelectedFile(list.getFile()); + _jSaveFileChooser.setFileFilter(getFileFilterForPlaylist(list)); int rc = _jSaveFileChooser.showSaveDialog(this); if (rc == JFileChooser.APPROVE_OPTION) { @@ -2041,6 +2071,12 @@ private boolean handleSavePlaylistAs(Playlist list) String extension = ((ExtensionFilter) _jSaveFileChooser.getFileFilter()).getExtension(); + if (list.getType() != PlaylistType.ITUNES && extension.equals("xml")) + { + JOptionPane.showMessageDialog(this, new JTransparentTextArea("listFix() can only save iTunes playlists as iTunes XML files. Please save to M3U or M3U8, which can be imported directly into iTunes.")); + return false; + } + // make sure file has correct extension String normalizedName = playlist.getName().trim().toLowerCase(); if (!Playlist.isPlaylist(playlist) || (!normalizedName.endsWith(extension))) @@ -2067,7 +2103,9 @@ protected Void doInBackground() throws Exception return null; } }; - ProgressDialog pd = new ProgressDialog(this, true, worker, "Saving...", false, false); + + ProgressDialog pd = new ProgressDialog(this, true, worker, "Saving...", list.getType() == PlaylistType.ITUNES || list.getType() == PlaylistType.XSPF, false); + pd.setMessage("Please wait while your playlist is saved to disk."); pd.setVisible(true); worker.get(); @@ -2347,7 +2385,7 @@ protected Boolean doInBackground() throws Exception } else if (rc == 1) { - return handleSavePlaylistAs(list); + return handleSaveAs(list); } else if (rc == 2) { diff --git a/src/listfix/view/controls/PlaylistEditCtrl.java b/src/listfix/view/controls/PlaylistEditCtrl.java index 7a110a86..583c3f2c 100644 --- a/src/listfix/view/controls/PlaylistEditCtrl.java +++ b/src/listfix/view/controls/PlaylistEditCtrl.java @@ -666,7 +666,8 @@ protected Void doInBackground() throws Exception return null; } }; - ProgressDialog pd = new ProgressDialog(getParentFrame(), true, worker, "Saving..."); + ProgressDialog pd = new ProgressDialog(getParentFrame(), true, worker, "Saving...", _playlist.getType() == PlaylistType.ITUNES || _playlist.getType() == PlaylistType.XSPF, false); + pd.setMessage("Please wait while your playlist is saved to disk."); pd.setVisible(true); worker.get(); } @@ -1308,7 +1309,7 @@ protected void done() private void _uiTableKeyPressed(java.awt.event.KeyEvent evt)//GEN-FIRST:event__uiTableKeyPressed {//GEN-HEADEREND:event__uiTableKeyPressed int keyVal = evt.getKeyCode(); - if (keyVal == KeyEvent.VK_DELETE) + if (keyVal == KeyEvent.VK_DELETE && _playlist.getType() != PlaylistType.ITUNES) { deleteSelectedRows(); } @@ -1561,12 +1562,13 @@ public void setPlaylist(Playlist list, boolean force) ((PlaylistTableModel) _uiTable.getModel()).fireTableDataChanged(); boolean hasPlaylist = _playlist != null; - _btnAdd.setEnabled(hasPlaylist); + + _btnAdd.setEnabled(hasPlaylist && _playlist.getType() != PlaylistType.ITUNES); _btnLocate.setEnabled(hasPlaylist); _btnMagicFix.setEnabled(hasPlaylist); - _btnReorder.setEnabled(hasPlaylist && _playlist.size() > 1); + _btnReorder.setEnabled(hasPlaylist && _playlist.getType() != PlaylistType.ITUNES && _playlist.size() > 1); _btnReload.setEnabled(hasPlaylist && _playlist.isModified()); - _btnPlay.setEnabled(hasPlaylist); + _btnPlay.setEnabled(hasPlaylist && _playlist.getType() != PlaylistType.ITUNES); _btnNextMissing.setEnabled(hasPlaylist && _playlist.getMissingCount() > 0); _btnPrevMissing.setEnabled(hasPlaylist && _playlist.getMissingCount() > 0); _btnSave.setEnabled(_playlist != null); @@ -1580,6 +1582,8 @@ public void setPlaylist(Playlist list, boolean force) { _playlist.addModifiedListener(listener); } + + _uiTable.setDragEnabled(_playlist.getType() != PlaylistType.ITUNES); } private void showWaitCursor(boolean isWaiting) @@ -1747,15 +1751,15 @@ public void valueChanged(ListSelectionEvent e) } boolean hasSelected = _uiTable.getSelectedRowCount() > 0; - _btnDelete.setEnabled(hasSelected); - _btnUp.setEnabled(_isSortedByFileIx && hasSelected && _uiTable.getSelectedRow() > 0); - _btnDown.setEnabled(_isSortedByFileIx && hasSelected && _uiTable.getSelectedRow() < _uiTable.getRowCount() - 1); - _btnPlay.setEnabled(_playlist != null && ( _uiTable.getSelectedRow() < 0 || ( _uiTable.getSelectedRows().length > 0 && selectedRowsContainFoundEntry() ) ) ); + _btnDelete.setEnabled(hasSelected && _playlist.getType() != PlaylistType.ITUNES); + _btnUp.setEnabled(_isSortedByFileIx && hasSelected && _playlist.getType() != PlaylistType.ITUNES && _uiTable.getSelectedRow() > 0); + _btnDown.setEnabled(_isSortedByFileIx && hasSelected && _playlist.getType() != PlaylistType.ITUNES && _uiTable.getSelectedRow() < _uiTable.getRowCount() - 1); + _btnPlay.setEnabled(_playlist != null && _playlist.getType() != PlaylistType.ITUNES && ( _uiTable.getSelectedRow() < 0 || ( _uiTable.getSelectedRows().length > 0 && selectedRowsContainFoundEntry() ) ) ); _btnReload.setEnabled(_playlist == null ? false : _playlist.isModified()); _btnSave.setEnabled(_playlist != null); _btnNextMissing.setEnabled(_playlist != null && _playlist.getMissingCount() > 0); _btnPrevMissing.setEnabled(_playlist != null && _playlist.getMissingCount() > 0); - _btnReorder.setEnabled(_playlist != null && _playlist.size() > 1); + _btnReorder.setEnabled(_playlist != null && _playlist.getType() != PlaylistType.ITUNES && _playlist.size() > 1); _btnInvert.setEnabled(hasSelected); if (_isSortedByFileIx) { diff --git a/src/listfix/view/dialogs/ProgressDialog.java b/src/listfix/view/dialogs/ProgressDialog.java index ac563e76..fbbdd6f5 100644 --- a/src/listfix/view/dialogs/ProgressDialog.java +++ b/src/listfix/view/dialogs/ProgressDialog.java @@ -121,6 +121,11 @@ public JLabel getProgressLabel() { return _progressTitle; } + + public void setMessage(String message) + { + _progressMessage.setText(message); + } private void initWorker(ProgressWorker worker) {