package com.limegroup.gnutella.gui.options;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.WindowConstants;
import com.limegroup.gnutella.gui.GUIMediator;
import com.limegroup.gnutella.gui.GUIUtils;
import com.limegroup.gnutella.gui.PaddedPanel;
import com.limegroup.gnutella.settings.SettingsHandler;
import com.limegroup.gnutella.util.CommonUtils;
/**
* This class constructs the options tree on the left side of the options dialog.
* <p>
* The panes that show up when a leaf in the tree is selected are created
* lazily in {@link OptionsPaneFactory}.
* <p>
* If you want to add a new {@link OptionsPane},
* add a call to {@link #addOption(String, String)} in the constructor here
* and add the construction of the pane to
* {@link OptionsPaneFactory#createOptionsPane(String)}.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
public final class OptionsConstructor {
/**
* Handle to the top-level <tt>JDialog</tt window that contains all
* of the other GUI components.
*/
private final JDialog DIALOG;
/**
* Constant for the default width of the options window.
*/
private final int OPTIONS_WIDTH = 600;
/**
* Constant for the default height of the options window.
*/
private final int OPTIONS_HEIGHT = 460;
/**
* Stored for convenience to allow using this in helper methods
* during construction.
*/
private final OptionsTreeManager TREE_MANAGER;
/**
* Stored for convenience to allow using this in helper methods
* during construction.
*/
private final OptionsPaneManager PANE_MANAGER;
static final String SAVE_KEY = "OPTIONS_SAVE_MAIN_TITLE";
static final String SHARED_KEY = "OPTIONS_SHARED_MAIN_TITLE";
static final String SPEED_KEY = "OPTIONS_SPEED_MAIN_TITLE";
static final String DOWNLOAD_KEY = "OPTIONS_DOWNLOAD_MAIN_TITLE";
static final String UPLOAD_KEY = "OPTIONS_UPLOAD_MAIN_TITLE";
static final String UPLOAD_BASIC_KEY = "OPTIONS_UPLOAD_BASIC_MAIN_TITLE";
static final String UPLOAD_SLOTS_KEY = "OPTIONS_UPLOAD_SLOTS_MAIN_TITLE";
static final String CONNECTIONS_KEY = "OPTIONS_CONNECTIONS_MAIN_TITLE";
static final String SHUTDOWN_KEY = "OPTIONS_SHUTDOWN_MAIN_TITLE";
static final String UPDATE_KEY = "OPTIONS_UPDATE_MAIN_TITLE";
static final String CHAT_KEY = "OPTIONS_CHAT_MAIN_TITLE";
static final String PLAYER_KEY = "OPTIONS_PLAYER_MAIN_TITLE";
static final String STATUS_BAR_KEY = "OPTIONS_STATUS_BAR_MAIN_TITLE";
static final String ITUNES_KEY = "OPTIONS_ITUNES_MAIN_TITLE";
static final String ITUNES_IMPORT_KEY = "OPTIONS_ITUNES_PREFERENCE_MAIN_TITLE";
static final String ITUNES_DAAP_KEY = "OPTIONS_ITUNES_DAAP_MAIN_TITLE";
static final String POPUPS_KEY = "OPTIONS_POPUPS_MAIN_TITLE";
static final String BUGS_KEY = "OPTIONS_BUGS_MAIN_TITLE";
static final String APPS_KEY = "OPTIONS_APPS_MAIN_TITLE";
static final String SEARCH_KEY = "OPTIONS_SEARCH_MAIN_TITLE";
static final String SEARCH_LIMIT_KEY = "OPTIONS_SEARCH_LIMIT_MAIN_TITLE";
static final String SEARCH_QUALITY_KEY = "OPTIONS_SEARCH_QUALITY_MAIN_TITLE";
static final String SEARCH_SPEED_KEY = "OPTIONS_SEARCH_SPEED_MAIN_TITLE";
static final String CONTENT_FILTER_KEY = "OPTIONS_CONTENT_FILTER_MAIN_TITLE";
static final String SEARCH_JUNK_KEY = "OPTIONS_SEARCH_JUNK_MAIN_TITLE";
static final String FILTERS_KEY = "OPTIONS_FILTERS_MAIN_TITLE";
static final String RESULTS_KEY = "OPTIONS_RESULTS_MAIN_TITLE";
static final String MESSAGES_KEY = "OPTIONS_MESSAGES_MAIN_TITLE";
static final String ADVANCED_KEY = "OPTIONS_ADVANCED_MAIN_TITLE";
static final String PREFERENCING_KEY = "OPTIONS_PREFERENCING_MAIN_TITLE";
static final String FIREWALL_KEY = "OPTIONS_FIREWALL_MAIN_TITLE";
static final String GUI_KEY = "OPTIONS_GUI_MAIN_TITLE";
static final String AUTOCOMPLETE_KEY = "OPTIONS_AUTOCOMPLETE_MAIN_TITLE";
static final String STARTUP_KEY = "OPTIONS_STARTUP_MAIN_TITLE";
static final String PROXY_KEY = "OPTIONS_PROXY_MAIN_TITLE";
/**
* The constructor create all of the options windows and their
* components.
*
* @param treeManager the <tt>OptionsTreeManager</tt> instance to
* use for constructing the main panels and
* adding elements
* @param paneManager the <tt>OptionsPaneManager</tt> instance to
* use for constructing the main panels and
* adding elements
*/
public OptionsConstructor(final OptionsTreeManager treeManager,
final OptionsPaneManager paneManager) {
TREE_MANAGER = treeManager;
PANE_MANAGER = paneManager;
final String title = GUIMediator.getStringResource("OPTIONS_TITLE");
final boolean shouldBeModal = !CommonUtils.isMacOSX();
DIALOG = new JDialog(GUIMediator.getAppFrame(), title, shouldBeModal);
DIALOG.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
GUIUtils.addHideAction((JComponent)DIALOG.getContentPane());
// make the window non-resizable only for operating systems
// where we know this will not cause a problem
if(CommonUtils.isWindows() || CommonUtils.isMacOSX()) {
DIALOG.setResizable(false);
}
DIALOG.setSize(OPTIONS_WIDTH, OPTIONS_HEIGHT);
// most Mac users expect changes to be saved when the window
// is closed, so save them
DIALOG.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
int answer = -1;
if(OptionsMediator.instance().isDirty()) {
answer = GUIMediator.showYesNoCancelMessage("OPTIONS_SAVE_ON_CLOSE");
if(answer == GUIMediator.YES_OPTION) {
OptionsMediator.instance().applyOptions();
SettingsHandler.save();
}
}
if(answer != GUIMediator.CANCEL_OPTION) {
DIALOG.dispose();
OptionsMediator.instance().disposeOptions();
}
} catch(IOException ioe) {
// nothing we should do here. a message should
// have been displayed to the user with more
// information
}
}
});
PaddedPanel mainPanel = new PaddedPanel();
Box splitBox = new Box(BoxLayout.X_AXIS);
Component treeComponent = TREE_MANAGER.getComponent();
Component paneComponent = PANE_MANAGER.getComponent();
splitBox.add(treeComponent);
splitBox.add(paneComponent);
mainPanel.add(splitBox);
mainPanel.add(Box.createVerticalStrut(17));
mainPanel.add(new OptionsButtonPanel().getComponent());
DIALOG.getContentPane().add(mainPanel);
addOption(OptionsMediator.ROOT_NODE_KEY, SAVE_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, SHARED_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, SPEED_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, DOWNLOAD_KEY);
// add the upload options group
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, UPLOAD_KEY);
addOption(UPLOAD_KEY, UPLOAD_BASIC_KEY);
addOption(UPLOAD_KEY, UPLOAD_SLOTS_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, CONNECTIONS_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, SHUTDOWN_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, UPDATE_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, CHAT_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, PLAYER_KEY);
addOption(OptionsMediator.ROOT_NODE_KEY, STATUS_BAR_KEY);
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, ITUNES_KEY);
if (CommonUtils.isMacOSX()) {
addOption(ITUNES_KEY, ITUNES_IMPORT_KEY);
}
addOption(ITUNES_KEY, ITUNES_DAAP_KEY);
if (!CommonUtils.isWindows() && !CommonUtils.isAnyMac()) {
addOption(OptionsMediator.ROOT_NODE_KEY, APPS_KEY);
}
addOption(OptionsMediator.ROOT_NODE_KEY, BUGS_KEY);
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, GUI_KEY);
addOption(GUI_KEY, POPUPS_KEY);
addOption(GUI_KEY, AUTOCOMPLETE_KEY);
// add the search options group
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, SEARCH_KEY);
addOption(SEARCH_KEY, SEARCH_LIMIT_KEY);
addOption(SEARCH_KEY, SEARCH_QUALITY_KEY);
addOption(SEARCH_KEY, SEARCH_SPEED_KEY);
// add the filters options group
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, FILTERS_KEY);
addOption(FILTERS_KEY, CONTENT_FILTER_KEY);
addOption(FILTERS_KEY, SEARCH_JUNK_KEY);
addOption(FILTERS_KEY, RESULTS_KEY);
addOption(FILTERS_KEY, MESSAGES_KEY);
// add the advanced options group
addGroupTreeNode(OptionsMediator.ROOT_NODE_KEY, ADVANCED_KEY);
addOption(ADVANCED_KEY, PREFERENCING_KEY);
addOption(ADVANCED_KEY, FIREWALL_KEY);
addOption(ADVANCED_KEY, PROXY_KEY);
if (GUIUtils.shouldShowStartOnStartupWindow()) {
addOption(ADVANCED_KEY, STARTUP_KEY);
}
PANE_MANAGER.show(SAVE_KEY);
}
/**
* Adds a parent node to the tree. This node serves navigational
* purposes only, and so has no corresponding <tt>OptionsPane</tt>.
* This method allows for multiple tiers of parent nodes, not only
* top-level parents.
*
* @param parentKey the key of the parent node to add this parent
* node to
* @param childKey the key of the new parent node that is a child of
* the <tt>parentKey</tt> argument
*/
private final void addGroupTreeNode(final String parentKey,
final String childKey) {
TREE_MANAGER.addNode(parentKey, childKey,
GUIMediator.getStringResource(childKey));
}
/**
* Adds the specified key and <tt>OptionsPane</tt> to current
* set of options. This adds this <tt>OptionsPane</tt> to the set of
* <tt>OptionsPane</tt>s the user can select.
*
* @param parentKey the key of the parent node to add the new node to
* @param pane the new pane that also supplies the name of the node
* in the tree
*/
private final void addOption(final String parentKey,
final String childKey) {
TREE_MANAGER.addNode(parentKey, childKey,
GUIMediator.getStringResource(childKey));
}
/**
* Makes the options window either visible or not visible depending on the
* boolean argument.
*
* @param visible <tt>boolean</tt> value specifying whether the options
* window should be made visible or not visible
* @param key the unique identifying key of the panel to show
*/
final void setOptionsVisible(boolean visible, final String key) {
if(!visible) {
DIALOG.dispose();
OptionsMediator.instance().disposeOptions();
} else {
if(GUIMediator.isAppVisible())
DIALOG.setLocationRelativeTo(GUIMediator.getAppFrame());
else {
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension dialogSize = DIALOG.getSize();
DIALOG.setLocation((screenSize.width - dialogSize.width)/2,
(screenSize.height - dialogSize.height)/2);
}
// initial tree selection
if (key == null)
TREE_MANAGER.setDefaultSelection();
else
TREE_MANAGER.setSelection(key);
DIALOG.setVisible(true);
}
}
/** Returns if the Options Box is visible.
* @return true if the Options Box is visible.
*/
public final boolean isOptionsVisible() {
return DIALOG.isVisible();
}
/**
* Returns the main <tt>JDialog</tt> instance for the options window,
* allowing other components to position themselves accordingly.
*
* @return the main options <tt>JDialog</tt> window
*/
JDialog getMainOptionsComponent() {
return DIALOG;
}
}