package com.limegroup.gnutella.gui.options.panes;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JTextField;
import com.limegroup.gnutella.gui.ButtonRow;
import com.limegroup.gnutella.gui.FileChooserHandler;
import com.limegroup.gnutella.gui.GUIMediator;
import com.limegroup.gnutella.gui.GUIUtils;
import com.limegroup.gnutella.gui.LabeledComponent;
import com.limegroup.gnutella.gui.SaveDirectoryHandler;
import com.limegroup.gnutella.gui.SizedTextField;
import com.limegroup.gnutella.settings.SharingSettings;
/**
* This class defines the panel in the options window that allows the user to
* change the directory for saving files.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
public final class SaveDirPaneItem extends AbstractPaneItem {
/**
* Constant for the key of the locale-specific <code>String</code> for the
* label on the component that allows to user to change the setting for this
* <tt>PaneItem</tt>.
*/
private final String OPTION_LABEL = "OPTIONS_SAVE_DIR_BOX_LABEL";
/**
* The SharedDirPaneItem, so new save directories can be shared.
*/
private final SharedDirPaneItem _shareData;
/**
* Handle to the <tt>JTextField</tt> that displays the save directory.
*/
private JTextField _saveField;
/**
* String for storing the initial save directory.
*/
private String _saveDirectory;
/**
* The mediatype table mediator that handles the per mediatype download
* directories table.
*/
private MediaTypeDownloadDirMediator _mtddMediator;
/**
* The mediator's description label id.
*/
private final String MEDIA_OPTION_LABEL = "OPTIONS_SAVE_MEDIATYPE_DIR_LABEL";
/**
* The constructor constructs all of the elements of this
* <tt>AbstractPaneItem</tt>. This includes the row of buttons that allow
* the user to select the save directory.
*
* @param key
* the key for this <tt>AbstractPaneItem</tt> that the
* superclass uses to generate strings
*/
public SaveDirPaneItem(final String key, SharedDirPaneItem shareStuff) {
super(key);
_shareData = shareStuff;
_saveField = new SizedTextField();
LabeledComponent comp = new LabeledComponent(OPTION_LABEL, _saveField,
LabeledComponent.TOP_LEFT);
String[] labelKeys = { "OPTIONS_SAVE_DIR_BROWSE_BUTTON_LABEL",
"OPTIONS_SAVE_DIR_DEFAULT_BUTTON_LABEL" };
String[] toolTipKeys = { "OPTIONS_SAVE_DIR_BROWSE_BUTTON_TIP",
"OPTIONS_SAVE_DIR_DEFAULT_BUTTON_TIP" };
ActionListener[] listeners = { new SelectSaveDirectoryListener(),
new DefaultListener() };
ButtonRow br = new ButtonRow(labelKeys, toolTipKeys, listeners,
ButtonRow.X_AXIS, ButtonRow.LEFT_GLUE);
add(comp.getComponent());
add(getVerticalSeparator());
add(br);
add(getVerticalSeparator());
_mtddMediator = new MediaTypeDownloadDirMediator(_saveField);
comp = new LabeledComponent(MEDIA_OPTION_LABEL,
_mtddMediator.getComponent(), LabeledComponent.TOP_LEFT,
LabeledComponent.NO_GLUE);
add(comp.getComponent());
Action[] actions = new AbstractAction[2];
actions[0] = _mtddMediator.getBrowseDirectoryAction();
actions[1] = _mtddMediator.getResetDirectoryAction();
br = new ButtonRow(actions, ButtonRow.X_AXIS, ButtonRow.LEFT_GLUE);
add(getVerticalSeparator());
add(br);
}
/**
* This listener responds to the selection of the default save directory
* and sets the current save directory to be the default.
*/
private class DefaultListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
_saveField.setText(SharingSettings.DEFAULT_SAVE_DIR.getAbsolutePath());
}
}
/**
* This listener displays a <tt>JFileChooser</tt> to the user, allowing
* the user to select the save directory.
*/
private class SelectSaveDirectoryListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
File dir = FileChooserHandler.getInputDirectory(MEDIATOR.getMainOptionsComponent());
// If the user cancelled the file chooser, simply return.
if (dir == null)
return;
// Otherwise, make sure they selected a valid directory that
// they can really write to.
if(!SaveDirectoryHandler.isSaveDirectoryValid(dir)) {
GUIMediator.showError("ERROR_INVALID_SAVE_DIRECTORY_SELECTION");
return;
}
try {
String newDir = dir.getCanonicalPath();
if(!newDir.equals(_saveDirectory)) {
_saveField.setText(newDir);
}
} catch (IOException ioe) {}
}
}
/**
* Defines the abstract method in <tt>AbstractPaneItem</tt>.
* <p>
*
* Sets the options for the fields in this <tt>PaneItem</tt> when the
* window is shown.
*/
public void initOptions() {
try {
File file = SharingSettings.getSaveDirectory();
if (file == null) {
throw (new FileNotFoundException());
}
_saveDirectory = file.getCanonicalPath();
} catch (FileNotFoundException fnfe) {
// simply use the empty string if we could not get the save
// directory.
_saveDirectory = "";
} catch (IOException ioe) {
_saveDirectory = "";
}
_saveField.setText(_saveDirectory);
_mtddMediator.initOptions();
}
/**
* Defines the abstract method in <tt>AbstractPaneItem</tt>.
* <p>
*
* Applies the options currently set in this window, displaying an error
* message to the user if a setting could not be applied.
*
* @throws IOException
* if the options could not be applied for some reason
*/
public boolean applyOptions() throws IOException {
final String save = _saveField.getText();
Set newDirs = new HashSet();
if(!save.equals(_saveDirectory)) {
try {
File saveDir = new File(save);
if(!saveDir.isDirectory()) {
if (!saveDir.mkdirs())
throw new IOException();
}
if(!_shareData.isGoingToBeShared(saveDir))
newDirs.add(saveDir);
SharingSettings.setSaveDirectory(saveDir);
_saveDirectory = save;
} catch(IOException ioe) {
GUIMediator.showError("ERROR_INVALID_SAVE_DIRECTORY");
_saveField.setText(_saveDirectory);
throw new IOException();
} catch(NullPointerException npe) {
GUIMediator.showError("ERROR_INVALID_SAVE_DIRECTORY");
_saveField.setText(_saveDirectory);
throw new IOException();
}
}
boolean restart = _mtddMediator.applyOptions(newDirs);
if(!newDirs.isEmpty()) {
String format = "";
for(Iterator i = newDirs.iterator(); i.hasNext(); )
format += GUIUtils.convertToNonBreakingSpaces(4, i.next().toString()) + "\n";
int response = GUIMediator.showYesNoMessage("OPTIONS_SHARED_NEW_SAVE_FOLDERS", format);
if(response == GUIMediator.YES_OPTION) {
for(Iterator i = newDirs.iterator(); i.hasNext(); )
_shareData.addAndKeepDirtyStatus((File)i.next());
}
}
return restart;
}
/**
* Gets the save directories.
*/
Collection getSaveDirectories() {
Set dirs = new HashSet();
dirs.add(new File(_saveDirectory));
_mtddMediator.addSaveDirs(dirs);
return dirs;
}
public boolean isDirty() {
return !SharingSettings.getSaveDirectory().equals(
new File(_saveField.getText())) || _mtddMediator.isDirty();
}
}