/* Copyright (C) 2003-2011 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package net.sf.jabref.external;
import net.sf.jabref.*;
import net.sf.jabref.gui.FileListEditor;
import net.sf.jabref.gui.FileListEntry;
import net.sf.jabref.gui.FileDialogs;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
/**
* Action for moving or renaming a file that is linked to from an entry in JabRef.
*/
public class MoveFileAction extends AbstractAction {
private JabRefFrame frame;
private EntryEditor eEditor;
private FileListEditor editor;
private boolean toFileDir;
public MoveFileAction(JabRefFrame frame, EntryEditor eEditor, FileListEditor editor,
boolean toFileDir) {
this.frame = frame;
this.eEditor = eEditor;
this.editor = editor;
this.toFileDir = toFileDir;
}
public void actionPerformed(ActionEvent event) {
int selected = editor.getSelectedRow();
if (selected == -1)
return;
FileListEntry flEntry = editor.getTableModel().getEntry(selected);
// Check if the current file exists:
String ln = flEntry.getLink();
boolean httpLink = ln.toLowerCase().startsWith("http");
if (httpLink) {
// TODO: notify that this operation cannot be done on remote links
}
// Get an absolute path representation:
String[] dirs = frame.basePanel().metaData().getFileDirectory(GUIGlobals.FILE_FIELD);
int found = -1;
for (int i=0; i<dirs.length; i++)
if (new File(dirs[i]).exists()) {
found = i;
break;
}
if (found < 0) {
JOptionPane.showMessageDialog(frame, Globals.lang("File_directory_is_not_set_or_does_not_exist!"),
Globals.lang("Move/Rename file"), JOptionPane.ERROR_MESSAGE);
return;
}
File file = new File(ln);
if (!file.isAbsolute()) {
file = Util.expandFilename(ln, dirs);
}
if ((file != null) && file.exists()) {
// Ok, we found the file. Now get a new name:
String extension = null;
if (flEntry.getType() != null)
extension = "." + flEntry.getType().getExtension();
File newFile = null;
boolean repeat = true;
while (repeat) {
repeat = false;
String chosenFile;
if (toFileDir) {
// Determine which name to suggest:
String suggName = Util.getLinkedFileName(eEditor.getDatabase(), eEditor.getEntry()).
concat(".").concat(flEntry.getType().extension);
CheckBoxMessage cbm = new CheckBoxMessage(Globals.lang("Move file to file directory?"),
Globals.lang("Rename to '%0'",suggName),
Globals.prefs.getBoolean("renameOnMoveFileToFileDir"));
int answer;
// Only ask about renaming file if the file doesn't have the proper name already:
if (!suggName.equals(file.getName()))
answer = JOptionPane.showConfirmDialog(frame, cbm, Globals.lang("Move/Rename file"),
JOptionPane.YES_NO_OPTION);
else
answer = JOptionPane.showConfirmDialog(frame, Globals.lang("Move file to file directory?"),
Globals.lang("Move/Rename file"), JOptionPane.YES_NO_OPTION);
if (answer != JOptionPane.YES_OPTION)
return;
Globals.prefs.putBoolean("renameOnMoveFileToFileDir", cbm.isSelected());
StringBuilder sb = new StringBuilder(dirs[found]);
if (!dirs[found].endsWith(File.separator))
sb.append(File.separator);
if (cbm.isSelected()) {
// Rename:
sb.append(suggName);
}
else {
// Do not rename:
sb.append(file.getName());
}
chosenFile = sb.toString();
} else {
chosenFile = FileDialogs.getNewFile(frame, file, extension, JFileChooser.SAVE_DIALOG, false);
}
if (chosenFile == null) {
return; // cancelled
}
newFile = new File(chosenFile);
// Check if the file already exists:
if (newFile.exists() && (JOptionPane.showConfirmDialog
(frame, "'" + newFile.getName() + "' " + Globals.lang("exists. Overwrite file?"),
Globals.lang("Move/Rename file"), JOptionPane.OK_CANCEL_OPTION)
!= JOptionPane.OK_OPTION)) {
if (!toFileDir)
repeat = true;
else
return;
}
}
if (!newFile.equals(file)) {
try {
boolean success = file.renameTo(newFile);
if (!success) {
success = Util.copyFile(file, newFile, true);
}
if (success) {
// Remove the original file:
file.delete();
// Relativise path, if possible.
String canPath = (new File(dirs[found])).getCanonicalPath();
if (newFile.getCanonicalPath().startsWith(canPath)) {
if ((newFile.getCanonicalPath().length() > canPath.length()) &&
(newFile.getCanonicalPath().charAt(canPath.length()) == File.separatorChar))
flEntry.setLink(newFile.getCanonicalPath().substring(1+canPath.length()));
else
flEntry.setLink(newFile.getCanonicalPath().substring(canPath.length()));
}
else
flEntry.setLink(newFile.getCanonicalPath());
eEditor.updateField(editor);
//JOptionPane.showMessageDialog(frame, Globals.lang("File moved"),
// Globals.lang("Move/Rename file"), JOptionPane.INFORMATION_MESSAGE);
frame.output(Globals.lang("File moved"));
} else {
JOptionPane.showMessageDialog(frame, Globals.lang("Move file failed"),
Globals.lang("Move/Rename file"), JOptionPane.ERROR_MESSAGE);
}
} catch (SecurityException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(frame, Globals.lang("Could not move file") + ": " + ex.getMessage(),
Globals.lang("Move/Rename file"), JOptionPane.ERROR_MESSAGE);
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(frame, Globals.lang("Could not move file") + ": " + ex.getMessage(),
Globals.lang("Move/Rename file"), JOptionPane.ERROR_MESSAGE);
}
}
}
else {
// File doesn't exist, so we can't move it.
JOptionPane.showMessageDialog(frame, Globals.lang("Could not find file '%0'.", flEntry.getLink()),
Globals.lang("File not found"), JOptionPane.ERROR_MESSAGE);
}
}
}