package controller;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import logging.LogUtil;
import model.ID3TagModel;
import model.ID3TagRegex;
import model.audio.Genres;
import model.audio.interfaces.IAudioFile;
import model.exception.AudioFileException;
import model.exception.AudioPlayerException;
import model.exception.ControllerInitException;
import model.filefilter.AudioFilter;
import model.filefilter.ImageFilter;
import model.filefilter.TxtFilter;
import model.progressbar.CounterProgressBar;
import model.progressbar.ChangeID3ProgressBar;
import model.progressbar.InProgressBar;
import model.progressbar.interfaces.ICancelCommand;
import model.progressbar.interfaces.IProgressBar;
import model.structure.FieldReplacerData;
import model.structure.ID3ImageData;
import model.structure.ID3LyricsData;
import model.structure.ID3TagData;
import model.transferhandler.FileFolderTransferHandler;
import model.transferhandler.FolderTransferHandler;
import model.util.ChooserUtil;
import model.util.Commons;
import model.util.FileUtil;
import model.util.Util;
import view.ID3TagTab;
import view.interfaces.AbstractTab;
import com.cf.structures.DataDouble;
import com.mpatric.mp3agic.NotSupportedException;
import config.Config;
import config.Constants;
import controller.interfaces.AbstractController;
import controller.interfaces.ICmdChangeID3Data;
import controller.interfaces.ICmdChangeImage;
import controller.interfaces.ICmdChangeLyrics;
import controller.interfaces.ICmdFieldReplacer;
import controller.interfaces.ICmdGenerateTabByFilename;
import controller.interfaces.ICmdImageSettings;
import controller.subcontroller.AudioPlayerController;
import controller.subcontroller.ChangeImageDataController;
import controller.subcontroller.ChangeLyricsDataController;
import controller.subcontroller.ChangeTagDataController;
import controller.subcontroller.FieldReplacerController;
import controller.subcontroller.GenByNameController;
import controller.subcontroller.ImageSettingsController;
public class ID3TagController extends AbstractController implements ListSelectionListener, TreeSelectionListener, FocusListener, ChangeListener {
/**
* the logger
*/
private final Logger logger = Logger.getLogger(this.getClass().getName());
/**
* the model
*/
private ID3TagModel model;
/**
* the window
*/
private ID3TagTab window;
/**
* the cancel command for progressbars
*/
private ICancelCommand cancelCmd;
/**
* Constructor
*/
public ID3TagController() {
super();
model = new ID3TagModel();
cancelCmd = new ICancelCommand() {
@Override
public void call() {
model.setStopFlag(true);
}
};
}
/*
* (non-Javadoc)
*
* @see
* controller.interfaces.AbstractController#init(view.interfaces.AbstractTab
* )
*/
@Override
public void init(AbstractTab tab) throws ControllerInitException {
this.window = (ID3TagTab) tab;
this.window.setTreeSelectionListener(this);
this.window.updateTree(Config.getInstance().getID3Root());
this.window.setrootTF(Config.getInstance().getID3Root());
this.window.setTableModel(model.getTableModel());
this.window.setGenres(Genres.getGenres());
this.window.setActionListener(this);
this.window.setListSelectionListener(this);
this.window.setFocusListener(this);
this.window.setChangeListener(this);
this.window.setTableTransferHandler(new FileFolderTransferHandler() {
private static final long serialVersionUID = -1571064726234858600L;
@Override
public void addFolder(String path) {
addAudioFiles(path);
}
@Override
public void addFiles(List<String> files) {
addAudioFiles(files);
}
});
this.window.setTreeTransferHandler(new FolderTransferHandler() {
private static final long serialVersionUID = 3016515574019264191L;
@Override
public void setFolder(String folder) {
rootOpenBPressed(folder, true);
}
});
}
/*
* (non-Javadoc)
*
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
@Override
public void update(Observable obs, Object obj) {
logger.log(Level.FINER, this.getClass().getName() + " got message from " + obs.getClass().getName());
}
/**
* delete image button pressed
*/
private void deleteImage() {
logger.log(Level.FINER, "delete image");
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
model.deleteAudioFileImage();
try {
window.setCoverImageData(null, null);
} catch (IOException e) {
// should never happen
logger.log(Level.SEVERE, "Error while resetting cover image:\n" + LogUtil.getStackTrace(e), e);
}
updateTable(i);
}
/**
* rescales the current image to the given width and height
*
* @param width
* new width
* @param height
* new height
*/
private void rescaleImage(int width, int height) {
logger.log(Level.FINER, "scale image to " + width + "x" + height);
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
try {
model.rescaleImage(width, height);
window.setAudioFileData(model.getCurrAudioFile());
} catch (IOException e) {
logger.log(Level.SEVERE, "Error while setting id3 data:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("rescaleError");
}
updateTable(i);
}
/**
* replaces the fields of the selected files with the given replacements
*
* @param data
* given replacement data
*/
private void replaceFields(FieldReplacerData data) {
int[] indices;
// get indices
if (data.isSelectAll()) {
indices = new int[model.getNumOfAudioFiles()];
for (int i = 0; i < model.getNumOfAudioFiles(); i++)
indices[i] = i;
} else
indices = window.getSelectedFiles();
if (indices == null || indices.length == 0)
return;
model.replaceFields(indices, data);
updateTable(indices);
try {
window.setAudioFileData(model.getCurrAudioFile());
} catch (IOException e) {
logger.log(Level.SEVERE, "File not Found:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("FileNotFound");
}
}
/**
* generates the ID3Tag using the filename regex and shows them in the
* change window
*
* @param data
* the filename regex
* @param all
* true if all is selected, else just the chosen audio files
*/
private void generateIDTagByFilename(ID3TagRegex data, boolean all) {
logger.log(Level.FINER, "create ID3Tag using Filename.");
int[] i;
if (all) {
i = new int[model.getNumOfAudioFiles()];
for (int j = 0; j < model.getNumOfAudioFiles(); j++)
i[j] = j;
} else
i = window.getSelectedFiles();
if (i == null || i.length == 0) {
window.showMessage("noFilesSelected");
return;
}
mainWindow.setWindowEnabled(false);
ChangeTagDataController con = new ChangeTagDataController();
con.setCloseCmd(new ICmdChangeID3Data() {
@Override
public void call(List<ID3TagData> data) {
mainWindow.setWindowEnabled(true);
if (data == null)
return;
changeId3TagData(data);
}
});
con.createWindow(model.getChangesAudioFileList(i, data));
}
/**
* changes the id3tag using the given changed data after confirmation
*
* @param lst
* given changes
*/
private void changeId3TagData(List<ID3TagData> lst) {
model.makesChanges(lst);
int[] i = window.getSelectedFiles();
if (i == null || i.length == 0)
return;
updateTable(i);
try {
window.setAudioFileData(model.getCurrAudioFile());
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found.");
}
}
/*
* (non-Javadoc)
*
* @see
* java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("rootOpenB"))
rootOpenBPressed("", false);
else if (e.getActionCommand().equals("deleteAllB"))
deleteAllBPressed();
else if (e.getActionCommand().equals("deleteFileB"))
deleteFileBPressed();
else if (e.getActionCommand().equals("addFileB"))
addFileBPressed();
else if (e.getActionCommand().equals("addFolderB"))
addFolderBPressed();
else if (e.getActionCommand().equals("loadB"))
loadBPressed();
else if (e.getActionCommand().equals("saveTagsB"))
saveTagsBPressed();
else if (e.getActionCommand().equals("addImageB"))
addImageBPressed();
else if (e.getActionCommand().equals("ImageSettingsB"))
ImageSettingsBPressed();
else if (e.getActionCommand().equals("searchImageB"))
searchImageBPressed();
else if (e.getActionCommand().equals("searchLyricsB"))
searchLyricsBPressed();
else if (e.getActionCommand().equals("fieldReplacerB"))
fieldReplacerBPressed();
else if (e.getActionCommand().equals("searchOnlineB"))
searchID3TagBPressed();
else if (e.getActionCommand().equals("generateByNameB"))
generateByNameBPressed();
else if (e.getActionCommand().equals("deleteTagB"))
deleteTagBPressed();
else if (e.getActionCommand().equals("undoB"))
undoBPressed();
else if (e.getActionCommand().equals("loadLyricsB"))
loadLyricsBPressed();
else if (e.getActionCommand().equals("saveLyricsB"))
saveLyricsBPressed();
else if (e.getActionCommand().equals("deleteLyricsB"))
deleteLyricsBPressed();
else if (e.getActionCommand().equals("saveImageB"))
saveImageBPressed();
else if (e.getActionCommand().equals("playAudioB"))
playButtonPressed();
else if (e.getActionCommand().equals("deleteFileHDDB"))
deleteFileFromHDDPressed();
else if (e.getActionCommand().equals("autoAddChB"))
autoAddChBPressed();
else if (e.getActionCommand().equals("urlRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("maxTracksRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("copyrightRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("encodedByRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("composerRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("commentRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("publisherRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("albumRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("albumArtistRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("genreRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("titleRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("artistRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("origArtistRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("imageAllRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("lyricsRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("trackRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("yearRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("cdRB"))
changerRBPressed(e.getActionCommand());
else if (e.getActionCommand().equals("maxCDRB"))
changerRBPressed(e.getActionCommand());
}
/**
* folder is dragged into tree or open folder is pressed
*
* @param folder
* the dragged folder, only important when isDrag is true
* @param isDrag
* true if dragged, else false
*/
private void rootOpenBPressed(String folder, boolean isDrag) {
logger.log(Level.FINER, "rootOpen button pressed or folder dragged.");
final File file;
if (isDrag)
file = new File(folder);
else
file = ChooserUtil.openFolder(window, new File(Config.getInstance().getID3Root()), System.getProperty("user.home"));
if (!checkFile(file, true))
return;
Config.getInstance().setID3Root(file.getAbsolutePath());
new Thread(new Runnable() {
@Override
public void run() {
window.setrootTF(file.getAbsolutePath());
InProgressBar bar = new InProgressBar();
bar.start();
window.updateTree(file.getAbsolutePath());
bar.stopBar();
}
}).start();
}
/**
* deletes the selected files from the HDD
*/
private void deleteFileFromHDDPressed() {
logger.log(Level.FINER, "delete file from hdd. index");
int[] indices = window.getSelectedFiles();
if (indices == null || indices.length == 0)
return;
int r = window.showConfirmationMessage("deleteFilesConfirm");
if (r != JOptionPane.YES_OPTION)
return;
for (int i = 0; i < indices.length; i++) {
if (!model.deleteFileFromHDD(indices[0]))
window.showMessage("deleteError", model.getAudioFile(indices[i]).getFilePath());
}
updateTable(null);
}
/**
* delets all files from the list
*/
private void deleteAllBPressed() {
logger.log(Level.FINER, "deleteAll button pressed.");
model.setCurrIndex(-1);
window.resetAudioFileData();
model.clearAudioFiles();
updateTable(null);
}
/**
* deletes the selected files from the list
*/
private void deleteFileBPressed() {
logger.log(Level.FINER, "deleteFile button pressed.");
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
model.setCurrIndex(-1);
window.resetAudioFileData();
model.deleteAudioFiles(i);
updateTable(null);
}
/**
* adds a file to the list
*/
private void addFileBPressed() {
logger.log(Level.FINER, "addFile button pressed.");
File file = ChooserUtil.openFile(window, new AudioFilter(), new File(Config.getInstance().getID3OpenFile()));
if (!checkFile(file, false))
return;
Config.getInstance().setId3OpenFile(file.getAbsolutePath());
List<String> lst = new ArrayList<>();
lst.add(file.getAbsolutePath());
addAudioFiles(lst);
}
/**
* adds a folder to the list
*/
private void addFolderBPressed() {
logger.log(Level.FINER, "addFolder button pressed.");
final File file = ChooserUtil.openFolder(window, new File(Config.getInstance().getID3OpenFolder()));
if (!checkFile(file, true))
return;
Config.getInstance().setId3OpenFolder(file.getAbsolutePath());
addAudioFiles(file.getAbsolutePath());
}
/**
* loads the selected folder in the tree
*/
private void loadBPressed() {
logger.log(Level.FINER, "load button pressed.");
final String path = getTreePath();
if (path == null || !checkFile(new File(path), true))
return;
model.clearAudioFiles();
addAudioFiles(path);
}
/**
* saves the changed tags
*/
private void saveTagsBPressed() {
// save made changes if there were some
ID3TagData data = window.getID3TagData();
boolean changes = model.makeChanges(data);
logger.log(Level.FINER, "saveTags button pressed. changes: " + changes);
final int[] i = window.getSelectedFiles();
new Thread(new Runnable() {
@Override
public void run() {
// get all indices or just selected ones
int[] indices;
if (window.getSaveAllChangedRB()) {
indices = new int[model.getNumOfAudioFiles()];
for (int j = 0; j < model.getNumOfAudioFiles(); j++)
indices[j] = j;
} else {
indices = i;
}
// check if something got changed
int changed = model.getChangedNumber(indices);
if (changed < 1) {
window.showMessage("noFilesChanged");
return;
}
// check if indices are selected
if (indices == null || indices.length == 0) {
window.showMessage("noFilesSelected");
return;
}
// get confirmation
if (Config.getInstance().isConfirmWriteTags()) {
int r = window.showConfirmationMessage("confirmWrite");
if (r != JOptionPane.YES_OPTION)
return;
}
window.setButtonsEnabled(false);
stopPlayers();
IProgressBar pb = new ChangeID3ProgressBar(changed);
try {
pb.setCancelCommand(cancelCmd);
pb.start();
model.writeAudioFiles(indices, pb);
} catch (NotSupportedException | AudioFileException e) {
window.showMessage("AudioFileParseError");
logger.log(Level.SEVERE, "Error while audio file parsing:\n" + LogUtil.getStackTrace(e), e);
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found.");
}
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setStopFlag(false);
window.setButtonsEnabled(true);
updateTable(i);
}
}).start();
}
/**
* adds an image to the current audio file
*/
private void addImageBPressed() {
logger.log(Level.FINER, "addImage button pressed.");
File file = ChooserUtil.openFile(window, new ImageFilter(), new File(Constants.DEFAULT_DIR));
if (!checkFile(file, false))
return;
try {
model.setAudioFileImageFromPath(file.getAbsolutePath());
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found.");
}
int[] i = window.getSelectedFiles();
updateTable(i);
}
/**
* saves the image of the file to HDD
*/
private void saveImageBPressed() {
logger.log(Level.FINER, "saveImage button pressed.");
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
File file = ChooserUtil.saveFile(window, null, new File(Constants.DEFAULT_DIR));
if (file == null)
return;
try {
model.writeID3TagImage(file.getAbsolutePath());
} catch (IllegalArgumentException e) {
window.showMessage("noID3TagImage");
logger.log(Level.SEVERE, "No id3tag Image to write:\n" + LogUtil.getStackTrace(e), e);
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found while writing id3tag Image.");
}
}
/**
* open the image settings window
*/
private void ImageSettingsBPressed() {
logger.log(Level.FINER, "Image Settings button pressed.");
int[] size = window.getImageSize();
if (size == null)
return;
mainWindow.setWindowEnabled(false);
ImageSettingsController con = new ImageSettingsController();
con.setCloseCommand(new ICmdImageSettings() {
@Override
public void call(int width, int height) {
mainWindow.setWindowEnabled(true);
if (width == -1 || height == -1)
return;
if (width == 0 || height == 0)
deleteImage();
// rescale
else
rescaleImage(width, height);
}
});
con.createWindow(size[0], size[1]);
}
/**
* searches for the covers online using the defined Collector
*/
private void searchImageBPressed() {
logger.log(Level.FINER, "searchImage button pressed.");
final int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new ChangeID3ProgressBar(i.length);
pb.setCancelCommand(cancelCmd);
pb.start();
List<DataDouble<ID3ImageData, ID3ImageData>> data = model.getCoverArtUpdate(i, pb);
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setStopFlag(false);
mainWindow.setWindowEnabled(false);
ChangeImageDataController con = new ChangeImageDataController();
con.setCloseCommand(new ICmdChangeImage() {
@Override
public void call(List<ID3ImageData> data) {
mainWindow.setWindowEnabled(true);
if (data == null)
return;
model.setCoverArt(data);
int[] i = window.getSelectedFiles();
updateTable(i);
try {
window.setAudioFileData(model.getCurrAudioFile());
} catch (IOException e) {
logger.log(Level.SEVERE, "File not Found.");
window.showMessage("FileNotFound");
}
}
});
con.createWindow(data);
}
}).start();
}
/**
* searches for lyrics online using the defined Collectors
*/
private void searchLyricsBPressed() {
logger.log(Level.FINER, "searchLyrics button pressed.");
final int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new ChangeID3ProgressBar(i.length);
pb.setCancelCommand(cancelCmd);
pb.start();
List<DataDouble<ID3LyricsData, ID3LyricsData>> data = model.getLyricsAudioFileUpdate(i, pb);
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setStopFlag(false);
mainWindow.setWindowEnabled(false);
ChangeLyricsDataController con = new ChangeLyricsDataController();
con.setCloseCommand(new ICmdChangeLyrics() {
@Override
public void call(List<ID3LyricsData> data) {
mainWindow.setWindowEnabled(true);
if (data == null)
return;
model.setLyrics(data);
int[] i = window.getSelectedFiles();
updateTable(i);
try {
window.setAudioFileData(model.getCurrAudioFile());
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found.");
}
}
});
con.createWindow(data);
}
}).start();
}
/**
* opens the field replacer
*/
private void fieldReplacerBPressed() {
logger.log(Level.FINER, "fieldReplacer button pressed.");
mainWindow.setWindowEnabled(false);
FieldReplacerController con = new FieldReplacerController();
con.setCloseCommand(new ICmdFieldReplacer() {
@Override
public void call(FieldReplacerData data) {
mainWindow.setWindowEnabled(true);
if (data == null)
return;
replaceFields(data);
}
});
con.createWindow();
}
/**
* searches for the ID3 Tag online using the defined Collectors
*/
private void searchID3TagBPressed() {
logger.log(Level.FINER, "serach ID3tag button pressed.");
final int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new ChangeID3ProgressBar(i.length);
pb.setCancelCommand(cancelCmd);
pb.start();
List<DataDouble<ID3TagData, ID3TagData>> data = model.getID3DataAudioFileUpdate(i, pb);
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setStopFlag(false);
mainWindow.setWindowEnabled(false);
ChangeTagDataController con = new ChangeTagDataController();
con.setCloseCmd(new ICmdChangeID3Data() {
@Override
public void call(List<ID3TagData> data) {
mainWindow.setWindowEnabled(true);
if (data == null)
return;
changeId3TagData(data);
}
});
con.createWindow(data);
}
}).start();
}
/**
* generates the ID3Tag by Filename window
*/
private void generateByNameBPressed() {
logger.log(Level.FINER, "generateByName button pressed.");
mainWindow.setWindowEnabled(false);
GenByNameController con = new GenByNameController();
con.setCloseCmd(new ICmdGenerateTabByFilename() {
@Override
public void call(ID3TagRegex regex, boolean selectAll) {
mainWindow.setWindowEnabled(true);
if (regex == null)
return;
generateIDTagByFilename(regex, selectAll);
}
});
con.createWindow();
}
/**
* deletes the tag of the chosen files
*/
private void deleteTagBPressed() {
logger.log(Level.FINER, "deleteTags button pressed.");
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
model.deleteTags(i);
window.resetAudioFileData();
updateTable(i);
}
/**
* undo button pressed
*/
private void undoBPressed() {
logger.log(Level.FINER, "undo button pressed.");
final int[] indices = window.getSelectedFiles();
if (indices == null || indices.length < 1)
return;
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new CounterProgressBar();
try {
pb.setMax(indices.length);
pb.setCancelCommand(cancelCmd);
for (int i = 0; i < indices.length; i++) {
model.undoChanges(i);
pb.nextStep();
}
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setStopFlag(false);
window.setAudioFileData(model.getCurrAudioFile());
} catch (AudioFileException e) {
logger.log(Level.SEVERE, "Error while audio file parsing:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("AudioFileParseError");
} catch (IOException e) {
logger.log(Level.SEVERE, "File not Found:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("FileNotFound");
}
updateTable(indices);
}
}).start();
}
/**
* loads the lyrics from a file
*/
private void loadLyricsBPressed() {
logger.log(Level.FINER, "loadLyrics button pressed.");
File f = ChooserUtil.openFile(window, new TxtFilter(), new File(Constants.DEFAULT_DIR));
if (f == null)
return;
try {
int[] i = window.getSelectedFiles();
String lyrics = FileUtil.readFile(f);
window.setLyricsTA(lyrics);
model.setLyrics(lyrics);
updateTable(i);
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found:\n" + LogUtil.getStackTrace(e), e);
}
}
/**
* saves the lyrics to a file
*/
private void saveLyricsBPressed() {
logger.log(Level.FINER, "saveLyrics button pressed.");
File f = ChooserUtil.saveFile(window, null, new File(Constants.DEFAULT_DIR));
if (f == null)
return;
try {
if (window.getLyricsTA().length() == 0) {
window.showMessage("noLyrics");
return;
}
FileUtil.writeFile(window.getLyricsTA(), f);
} catch (IOException e) {
window.showMessage("FileNotFound");
logger.log(Level.SEVERE, "File not Found.");
}
}
/**
* deletes the selected lyrics
*/
private void deleteLyricsBPressed() {
logger.log(Level.FINER, "deleteLyrivs button pressed.");
// already empty -> do nothing
if (window.getLyricsTA().length() == 0)
return;
int[] i = window.getSelectedFiles();
model.setLyrics("");
window.setLyricsTA("");
updateTable(i);
}
/**
* plays the audio file using the defined player
*/
private void playButtonPressed() {
logger.log(Level.FINER, "play audio button pressed. default player: " + Config.getInstance().isUseCustomPlayer());
// use custom or default player
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
IAudioFile file = model.getAudioFile(i[0]);
// use custom player
if (Config.getInstance().isUseCustomPlayer()) {
try {
logger.log(Level.FINER, "call custom player cmd: " + Config.getInstance().getCustomPlayerCmd() + " \"" + file.getFilePath() + "\"");
model.startCustomPlayer(file.getFilePath());
} catch (IOException e) {
logger.log(Level.SEVERE, "Error while loading custom player:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("AudioPlayerError");
}
}
// use default player
else {
try {
AudioPlayerController con = new AudioPlayerController(file.getFilePath(), file.getName(), (int) file.getAudioLength(), file.getFrameCount());
addObserver(con);
con.createWindow();
} catch (AudioPlayerException e) {
logger.log(Level.SEVERE, "Error while loading custom player:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("AudioPlayerError");
}
}
}
/**
* auto add checkbox clicked
*/
private void autoAddChBPressed() {
logger.log(Level.FINER, "autoAddChB pressed: " + window.getautoAddChB());
if (window.getautoAddChB())
window.setLoadButtonEnabled(false);
else
window.setLoadButtonEnabled(true);
}
/**
* clicked on of the "change all" radiobuttons
*
* @param actionCmd
* the given actioncommand to identify which radiobutton was
* pressed
*/
private void changerRBPressed(String actionCmd) {
window.resetRB();
// backup last made changes
ID3TagData data = window.getID3TagData();
boolean changed = model.makeChanges(data);
logger.log(Level.FINER, "changerRB pressed: " + actionCmd + " changes: " + changed);
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
switch (actionCmd) {
case "titleRB": {
model.changeAudioFileComponent(actionCmd, window.gettitleTF(), i);
break;
}
case "artistRB": {
model.changeAudioFileComponent(actionCmd, window.getartistTF(), i);
break;
}
case "albumArtistRB": {
model.changeAudioFileComponent(actionCmd, window.getalbumArtistTF(), i);
break;
}
case "albumRB": {
model.changeAudioFileComponent(actionCmd, window.getalbumTF(), i);
break;
}
case "yearRB": {
model.changeAudioFileComponent(actionCmd, window.getyearTF(), i);
break;
}
case "trackRB": {
model.changeAudioFileComponent(actionCmd, Integer.parseInt(window.getTrackNr()), i);
break;
}
case "maxTracksRB": {
model.changeAudioFileComponent(actionCmd, window.getMaxTracks(), i);
break;
}
case "cdRB": {
model.changeAudioFileComponent(actionCmd, window.getCurrCD(), i);
break;
}
case "maxCDRB": {
model.changeAudioFileComponent(actionCmd, window.getMaxCD(), i);
break;
}
case "genreRB": {
model.changeAudioFileComponent(actionCmd, window.getGenre(), i);
break;
}
case "publisherRB": {
model.changeAudioFileComponent(actionCmd, window.getPublisherTF(), i);
break;
}
case "commentRB": {
model.changeAudioFileComponent(actionCmd, window.getcommentTF(), i);
break;
}
case "composerRB": {
model.changeAudioFileComponent(actionCmd, window.getcomposerTF(), i);
break;
}
case "origArtistRB": {
model.changeAudioFileComponent(actionCmd, window.getorigArtistTF(), i);
break;
}
case "copyrightRB": {
model.changeAudioFileComponent(actionCmd, window.getcopyrightTF(), i);
break;
}
case "urlRB": {
model.changeAudioFileComponent(actionCmd, window.geturlTF(), i);
break;
}
case "encodedByRB": {
model.changeAudioFileComponent(actionCmd, window.getencodedByTF(), i);
break;
}
case "imageAllRB": {
model.changeAudioFileComponent(actionCmd, null, i);
break;
}
case "lyricsRB": {
model.changeAudioFileComponent(actionCmd, window.getLyricsTA(), i);
break;
}
}
updateTable(i);
}
/*
* tree value selected
*
* (non-Javadoc)
*
* @see
* javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event
* .TreeSelectionEvent)
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
if (!window.getautoAddChB())
return;
final String path = getTreePath();
if (path == null)
return;
if (!new File(path).exists()) {
logger.log(Level.FINER, "file: " + path + " doesnt exist.");
window.showMessage("FileNotFound");
return;
}
logger.log(Level.FINER, "selected Tree Element: " + path);
model.clearAudioFiles();
addAudioFiles(path);
}
/**
* gets the Path selected in the Tree
*/
private String getTreePath() {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) window.getFilesTree().getLastSelectedPathComponent();
if (node == null)
return null;
logger.log(Level.FINER, "selected treenode: " + node.getUserObject());
String folderPath = FileUtil.getFilePath(window.getrootTF()) + "/" + Util.getPathFromJTree(node);
logger.log(Level.FINER, "created Path: " + folderPath);
return folderPath;
}
/*
* table value changed
*
* (non-Javadoc)
*
* @see
* javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event
* .ListSelectionEvent)
*/
@Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
logger.log(Level.FINER, "Table value changed");
boolean updateTable = false;
if (model.getCurrIndex() != -1) {
updateTable = true;
ID3TagData data = window.getID3TagData();
boolean changed = model.makeChanges(data);
logger.log(Level.FINER, "Table changed. changes: " + changed);
}
int[] i = window.getSelectedFiles();
if (i == null || i.length < 1)
return;
logger.log(Level.FINER, "select audio file at index: " + i[0]);
model.setCurrIndex(i[0]);
IAudioFile file = model.getCurrAudioFile();
try {
window.setAudioFileData(file);
} catch (IOException e1) {
window.showMessage("AudioFileImageLoadError");
}
if (updateTable)
updateTable(i);
}
/*
* (non-Javadoc)
*
* @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
*/
@Override
public void focusLost(FocusEvent e) {
// do nothing
}
/*
* (non-Javadoc)
*
* @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
*/
@Override
public void focusGained(FocusEvent e) {
ID3TagData data = window.getID3TagData();
boolean changed = model.makeChanges(data);
logger.log(Level.FINER, "Focus gained. changes: " + changed);
if (changed) {
int[] i = window.getSelectedFiles();
updateTable(i);
}
}
/*
* (non-Javadoc)
*
* @see
* javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent
* )
*/
@Override
public void stateChanged(ChangeEvent arg0) {
ID3TagData data = window.getID3TagData();
boolean changed = model.makeChanges(data);
logger.log(Level.FINER, "Tab changed. changes: " + changed);
if (changed) {
int[] i = window.getSelectedFiles();
updateTable(i);
}
}
/**
* deselects the table listener and updates the table, selects the given
* indices or the current audio file or null for no selections
*
* @param indices
* given indices or null
*/
private void updateTable(int[] indices) {
window.removeListSelectionListener(this);
window.saveTableWidth();
window.setTableModel(model.getTableModel());
if (indices == null || indices.length < 1) {
if (model.getCurrIndex() != -1)
window.setSelectedFile(model.getCurrIndex());
} else
window.setSelectedFiles(indices);
window.setListSelectionListener(this);
}
/**
* stops all by this application opened player
*/
private void stopPlayers() {
logger.log(Level.FINER, "Stop players.");
// stop custom player
setChanged();
notifyObservers("closePlayer");
// stop player
model.stopPlayer();
}
/**
* adds the folder to the list
*
* @param path
* given folder path
*/
private void addAudioFiles(final String path) {
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new CounterProgressBar();
try {
int c = Commons.countAudioFiles(path, window.getrecursiveChB());
pb.setCancelCommand(cancelCmd);
pb.setMax(c);
pb.start();
model.addAudioFiles(path, window.getrecursiveChB(), pb);
} catch (AudioFileException e) {
logger.log(Level.SEVERE, "Error while reading audio files:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("AudioFileParseError");
}
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setCurrIndex(-1);
window.resetAudioFileData();
updateTable(null);
model.setStopFlag(false);
}
}).start();
}
/**
* adds the given files to the list
*
* @param files
* given file list
*/
private void addAudioFiles(final List<String> files) {
new Thread(new Runnable() {
@Override
public void run() {
IProgressBar pb = new CounterProgressBar();
try {
int c = files.size();
pb.setCancelCommand(cancelCmd);
pb.setMax(c);
pb.start();
for (String f : files) {
model.addAudioFile(f);
pb.nextStep();
}
} catch (AudioFileException e) {
logger.log(Level.SEVERE, "Error while reading audio files:\n" + LogUtil.getStackTrace(e), e);
window.showMessage("AudioFileParseError");
}
Util.sleep(Constants.REFRESH_DELAY);
pb.stopBar();
model.setCurrIndex(-1);
window.resetAudioFileData();
updateTable(null);
model.setStopFlag(false);
}
}).start();
}
/**
* checks if the file/folder exists and is not null
*
* @param file
* the file or folder
* @param isFolder
* true for a folder, else false
*
* @return true if valid, else false
*/
private boolean checkFile(File file, boolean isFolder) {
if (file == null)
return false;
if (!new File(file.getAbsolutePath()).exists()) {
if (isFolder) {
logger.log(Level.FINER, "file: " + file.getAbsolutePath() + " doesnt exist.");
window.showMessage("FileNotFound");
} else {
logger.log(Level.FINER, "folder: " + file.getAbsolutePath() + " doesnt exist.");
window.showMessage("FolderNotFound");
}
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see controller.interfaces.AbstractController#saveConfig()
*/
@Override
public void saveConfig() {
Config.getInstance().setID3Recursive(window.getrecursiveChB());
Config.getInstance().setID3AutoAdd(window.getautoAddChB());
Config.getInstance().setID3AllChanged(window.getSaveAllChangedRB());
}
}