/*
* XNap - A peer-to-peer framework and client
*
* See AUTHORS for copyright information.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package xnap.gui;
import xnap.*;
import xnap.cmdl.*;
import xnap.gui.action.*;
import xnap.gui.event.*;
import xnap.gui.table.*;
import xnap.gui.util.GUIHelper;
import xnap.io.*;
import xnap.net.*;
import xnap.plugin.*;
import xnap.user.*;
import xnap.util.*;
import xnap.util.audio.*;
import xnap.util.event.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import org.apache.log4j.Logger;
import ziga.gui.WindowsDesktopIndicator;
public class XNapFrame extends JFrame
implements ActionListener, ChangeListener, PropertyChangeListener,
StateListener, CommandLineSupport, StatusListener
{
//--- Constant(s) ---
public static final int PLUGIN_MENU_INDEX = 2;
public static final int PLUGIN_STATUS_PANEL_INDEX = 0;
public static final String CMD_HISTORY_FILENAME
= FileHelper.getHomeDir() + "cmd_history";
//--- Data field(s) ---
private static Logger logger = Logger.getLogger(XNapFrame.class);
private static XNapFrame singleton = null;
private static Preferences prefs = Preferences.getInstance();
private AbstractCommand[] commands = {
new ExitCmd()
};
private EditableComboBox ecbCmdl;
private JToolBar jtbMain;
private JToolBar jtbCmdl;
private JMenuBar jmenubar;
private int tbCount;
private ToggableIconPane pane;
private ChatPanel apChat;
private HotlistPanel apHotlist;
private LibraryPanel libraryPanel;
private SearchPanel searchPanel;
private StatusPanel statusPanel;
private TransferPanel transferPanel;
/**
* Needed to select menuitem if plugin is enabled or disabled.
*/
private Hashtable pluginStateMenuItemByPlugin = new Hashtable();
private Hashtable pluginMenuByPlugin = new Hashtable();
private JCheckBoxMenuItem jmiUseTabbedPane;
private JCheckBoxMenuItem jmiUseTabbedTransferPane;
// private JCheckBoxMenuItem jmiUseSocksProxy;
private JCheckBoxMenuItem jmiChatAway;
private JPanel jpStatus;
private JMenu viewMenu;
private ViewActionListener viewListener = new ViewActionListener();
/**
* Maps plugin name to JMenuItem in view menu.
*/
private Hashtable viewMap = new Hashtable();
private PreferencesAction acPreferences = new PreferencesAction();
private ShowToolbarAction acShowCmdlToolbar;
private ShowToolbarAction acShowMainToolbar;
private WindowsDesktopIndicator wdi;
public int chatIndex = 0;
private static int focusExceptions = 0;
//--- Constructor(s) ---
public XNapFrame()
{
singleton = this;
// make sure we create the gui kind
GUIPluginManager.getInstance();
if (Updater.isZigaDllLoaded()) {
wdi = new WindowsDesktopIndicator(this);
wdi.load("xnap.ico", "XNap");
}
if (Updater.isMacOSX()) {
try {
Class c = Class.forName("xnap.platform.macos.MacOSHandler");
Method m = c.getMethod("register", null);
m.invoke(null, null);
}
catch (Exception e) {
logger.warn("could not register mac os handler", e);
}
}
initialize();
// init singletons
Updater.start();
// enable plugins
GUIPluginManager.getInstance().addStateListener(this);
GUIPluginManager.getInstance().enablePlugins
(prefs.getEnabledGUIPlugins());
if (prefs.getAutoVersionCheck()) {
checkForUpdate(false);
}
/*
// show info
if (VersionParser.compare(prefs.getLastLaunchVer(),
XNap.VERSION) < 0) {
HTMLDialog.showDialog(this, "XNap2 Info",
"http://xnap.sf.net/xnap2.html");
}
*/
}
//--- Method(s) ---
private void initialize()
{
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
SplashWindow.setText(XNap.tr("Setting up Look & Feel"));
SplashWindow.setProgress(15);
ThemeManager.installLookAndFeels();
updateLookAndFeel();
SplashWindow.setText(XNap.tr("Setting up Gui"));
SplashWindow.setProgress(20);
// tool bars
initializeToolbars();
// panels
initializePanels();
SplashWindow.setText(XNap.tr("Setting up Menus"));
SplashWindow.setProgress(50);
// menu
initializeMenu();
SplashWindow.setText(XNap.tr("Setting up Frame"));
SplashWindow.setProgress(65);
// frame
setTitle(XNap.tr("XNap - Java Filesharing Client"));
ImageIcon image = XNapFrame.getSmallIcon("xnap.png");
if (image != null)
setIconImage(image.getImage());
JPanel jpMain = new JPanel(new BorderLayout());
jpMain.add(pane, BorderLayout.CENTER);
jpMain.add(jtbCmdl, BorderLayout.SOUTH);
JPanel jpBottom = new JPanel(new BorderLayout());
jpBottom.add(statusPanel, BorderLayout.CENTER);
jpBottom.add(jpStatus, BorderLayout.EAST);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(jtbMain, BorderLayout.NORTH);
getContentPane().add(jpMain, BorderLayout.CENTER);
getContentPane().add(jpBottom, BorderLayout.SOUTH);
pack();
setBounds(prefs.getWindowX(), prefs.getWindowY(),
prefs.getWindowWidth(), prefs.getWindowHeight());
// close app if someone clicks on X
addWindowListener(new WindowListener());
prefs.addPropertyChangeListener(this);
// setup listener
Console.getInstance().setConsole(ConsoleDialog.getInstance());
Executer.installHandler(this);
GUINotifier.getGUIInstance().setStatusListener(this);
// wizard
if (prefs.getLastLaunchReleaseNr() == -1) {
SplashWindow.setText(XNap.tr("Loading Wizard"));
StartupWizardDialog.showDialog(this, true);
}
SplashWindow.setProgress(95);
}
private void initializeToolbars()
{
// main toolbar
jtbMain = new JToolBar(XNap.tr("Show Main Toolbar"));
jtbMain.add(acPreferences);
jtbMain.addSeparator();
jtbMain.add(ActionHelper.cutAction);
jtbMain.add(ActionHelper.copyAction);
jtbMain.add(ActionHelper.pasteAction);
jtbMain.addSeparator();
tbCount = jtbMain.getComponentCount();
// command line
jtbCmdl = new JToolBar(XNap.tr("Show Command Line Toolbar"));
jtbCmdl = new JToolBar(XNap.tr("Show Command Line"));
jtbCmdl.add(new JLabel(XNap.tr("Command", 1)));
CmdlAction a = new CmdlAction();
ecbCmdl = new EditableComboBox(a);
ecbCmdl.readHistoryFile(new File(CMD_HISTORY_FILENAME));
jtbCmdl.add(ecbCmdl);
jtbCmdl.add(new JButton(a));
}
private void initializePanels()
{
// tabbed pane / icon split pane
pane = new ToggableIconPane(prefs.getUseTabbedPane());
pane.addChangeListener(this);
SplashWindow.setProgress(25);
// search
searchPanel = new SearchPanel();
searchPanel.setName("search");
//searchPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
searchPanel.setStatusListener(this);
pane.addTab(XNap.tr("Search"),
XNapFrame.getBigIcon("find.png"), searchPanel);
SplashWindow.setProgress(30);
// transfer
transferPanel = new TransferPanel();
transferPanel.setName("transfer");
transferPanel.addPropertyChangeListener(this);
transferPanel.setStatusListener(this);
pane.addTab(XNap.tr("Transfer"),
XNapFrame.getBigIcon("connect.png"), transferPanel);
SplashWindow.setText(XNap.tr("Setting up Library Panel"));
SplashWindow.setProgress(35);
// chat
apChat = new ChatPanel();
apChat.setName("chat");
apChat.setStatusListener(this);
apChat.addChangeListener(this);
pane.addTab(XNap.tr("Chat"),
XNapFrame.getBigIcon("mail_generic.png"), apChat);
chatIndex = pane.getTabCount() - 1;
// hotlist
apHotlist = new HotlistPanel();
apHotlist.setName("hotlist");
apHotlist.setStatusListener(this);
pane.addTab(XNap.tr("Hotlist"),
// XNapFrame.getIcon("users.png"), apHotlist);
XNapFrame.getBigIcon("kdmconfig.png"), apHotlist);
// library
libraryPanel = new LibraryPanel();
libraryPanel.setName("library");
libraryPanel.setStatusListener(this);
pane.addTab(XNap.tr("Library"),
XNapFrame.getBigIcon("contents.png"), libraryPanel);
SplashWindow.setProgress(40);
initializeStatusPanel();
SplashWindow.setProgress(45);
}
private void initializeStatusPanel()
{
// status panel
statusPanel = new StatusPanel(10000);
//statusPanel.setText(XNap.tr("Please use Help -> Send Feedback and let us know what you think of XNap"), -1);
jpStatus = new JPanel();
BoxLayout bx = new BoxLayout(jpStatus, BoxLayout.X_AXIS);
jpStatus.setLayout(bx);
StatusPanel spDownloads
= new StatusPanel(XNapFrame.getSmallIcon("down.png"));
DownloadQueue.getInstance().setStatusListener(spDownloads);
jpStatus.add(spDownloads);
StatusPanel spUploads
= new StatusPanel(XNapFrame.getSmallIcon("up.png"));
UploadQueue.getInstance().setStatusListener(spUploads);
jpStatus.add(spUploads);
StatusPanel spRepository = new StatusPanel();
Repository.getInstance().setStatusListener(spRepository);
jpStatus.add(spRepository);
if (Updater.isMacOSX()) {
// the aqua look and feel adds a small resize control in the
// lower right corner which overlaps the status panel
// therefore we add a little offset
jpStatus.add(Box.createHorizontalStrut(15));
}
}
private void initializeMenu()
{
setJMenuBar(new JMenuBar());
initializeFileMenu();
initializeEditMenu();
initializeViewMenu();
initializePluginsMenu();
initializeChatMenu();
initializeSettingsMenu();
initializeHelpMenu();
// mnemomics are a foreign concept to Mac OS X
// http://developer.apple.com/techpubs/macosx/Java/JavaDevelopment/JavaDevonMacOSX.pdf
if (!Updater.isMacOSX()) {
GUIHelper.setMnemonics(getJMenuBar());
}
}
private void initializeFileMenu()
{
JMenu fileMenu = new JMenu(XNap.tr("File"));
JMenuItem jmiRebuildLibrary
= new JMenuItem(new UpdateRepositoryAction());
fileMenu.add(jmiRebuildLibrary);
JMenuItem jmiWizard = new JMenuItem(XNap.tr("Setup Wizard") + "...");
jmiWizard.addActionListener(this);
fileMenu.add(jmiWizard);
fileMenu.addSeparator();
JMenuItem jmiExit = new JMenuItem(XNap.tr("Exit"));
jmiExit.addActionListener(this);
fileMenu.add(jmiExit);
getJMenuBar().add(fileMenu);
}
private void initializeEditMenu()
{
JMenu jmEdit = new JMenu(XNap.tr("Edit"));
JMenuItem jmiCut = new JMenuItem(ActionHelper.cutAction);
jmEdit.add(jmiCut);
JMenuItem jmiCopy = new JMenuItem(ActionHelper.copyAction);
jmEdit.add(jmiCopy);
JMenuItem jmiPaste = new JMenuItem(ActionHelper.pasteAction);
jmEdit.add(jmiPaste);
jmEdit.addSeparator();
JMenuItem jmiPurgeHistory = new JMenuItem(new PurgeHistoryAction());
jmEdit.add(jmiPurgeHistory);
getJMenuBar().add(jmEdit);
}
private void initializeChatMenu()
{
JMenu jmChat = new JMenu(XNap.tr("Chat"));
jmiChatAway = new JCheckBoxMenuItem(new ChatAwayAction());
jmiChatAway.setSelected(prefs.getSendChatAwayMessage());
jmChat.add(jmiChatAway);
getJMenuBar().add(jmChat);
}
private void initializePluginMenus()
{
}
private void initializePluginsMenu()
{
// add disabled menus from gui plugins
IPlugin[] plugins = PluginManager.getInstance().getPlugins();
for (int i = 0; i < plugins.length; i++) {
if (plugins[i] instanceof IGUIPlugin) {
JMenu jm = ((IGUIPlugin)plugins[i]).getMenu();
if (jm != null) {
jm.setEnabled(false);
getJMenuBar().add(jm);
}
}
}
JMenu pluginsMenu = new JMenu(XNap.tr("Plugins"));
JMenu jmViewers = new JMenu(XNap.tr("Viewers"));
pluginsMenu.add(jmViewers);
ActionListener pluginListener = new PluginActionListener();
for (int i = 0; i < plugins.length; i++) {
JCheckBoxMenuItem item
= new JCheckBoxMenuItem(plugins[i].getName());
item.setActionCommand(plugins[i].getClass().getName());
item.addActionListener(pluginListener);
item.setSelected(plugins[i].isEnabled());
pluginStateMenuItemByPlugin.put(plugins[i], item);
if (plugins[i] instanceof IViewerPlugin) {
jmViewers.add(item);
}
else {
pluginsMenu.add(item, 0);
}
}
// pluginsMenu.addSeparator();
// JMenuItem jmi = new JMenuItem(new InstallPluginsAction());
// pluginsMenu.add(jmi);
getJMenuBar().add(pluginsMenu);
}
private void initializeViewMenu()
{
// view
viewMenu = new JMenu(XNap.tr("View"));
JMenuItem jmiSearch = new JMenuItem(XNap.tr("Search"));
GUIHelper.setAccelerator(jmiSearch, KeyEvent.VK_S);
jmiSearch.addActionListener(viewListener);
viewMenu.add(jmiSearch);
JMenuItem jmiTransfer = new JMenuItem(XNap.tr("Transfer"));
GUIHelper.setAccelerator(jmiTransfer, KeyEvent.VK_T);
jmiTransfer.addActionListener(viewListener);
viewMenu.add(jmiTransfer);
JMenuItem jmiChat = new JMenuItem(XNap.tr("Chat"));
// GUIHelper.setAccelerator(jmiChat, KeyEvent.VK_H);
jmiChat.addActionListener(viewListener);
viewMenu.add(jmiChat);
JMenuItem jmiHotlist = new JMenuItem(XNap.tr("Hotlist"));
jmiHotlist.addActionListener(viewListener);
viewMenu.add(jmiHotlist);
JMenuItem jmiLibrary = new JMenuItem(XNap.tr("Library"));
GUIHelper.setAccelerator(jmiLibrary, KeyEvent.VK_L);
jmiLibrary.addActionListener(viewListener);
viewMenu.add(jmiLibrary);
viewMenu.addSeparator();
JMenuItem jmiConsole = new JMenuItem(XNap.tr("Console"));
GUIHelper.setAccelerator(jmiConsole, KeyEvent.VK_W);
jmiConsole.addActionListener(this);
viewMenu.add(jmiConsole);
getJMenuBar().add(viewMenu);
}
private void initializeSettingsMenu()
{
JMenu settingsMenu = new JMenu(XNap.tr("Settings"));
acShowMainToolbar = new ShowToolbarAction(jtbMain,
prefs.getShowMainToolbar());
JCheckBoxMenuItem jmiShowMainTB
= new JCheckBoxMenuItem(acShowMainToolbar);
jmiShowMainTB.setSelected(prefs.getShowMainToolbar());
settingsMenu.add(jmiShowMainTB);
acShowCmdlToolbar = new ShowToolbarAction(jtbCmdl,
prefs.getShowCmdlToolbar());
JCheckBoxMenuItem jmiShowCmdlTB
= new JCheckBoxMenuItem(acShowCmdlToolbar);
jmiShowCmdlTB.setSelected(prefs.getShowCmdlToolbar());
settingsMenu.add(jmiShowCmdlTB);
settingsMenu.addSeparator();
jmiUseTabbedPane = new JCheckBoxMenuItem(new UseTabbedPaneAction());
jmiUseTabbedPane.setSelected(prefs.getUseTabbedPane());
settingsMenu.add(jmiUseTabbedPane);
jmiUseTabbedTransferPane
= new JCheckBoxMenuItem(new UseTabbedTransferPaneAction());
jmiUseTabbedTransferPane.setSelected(prefs.getUseTabbedTransferPane());
settingsMenu.add(jmiUseTabbedTransferPane);
// jmiUseSocksProxy = new JCheckBoxMenuItem(new UseSocksProxyAction());
// jmiUseSocksProxy.setSelected(prefs.getUseSocksProxy());
// settingsMenu.add(jmiUseSocksProxy);
settingsMenu.addSeparator();
JMenu jmTable = new JMenu(XNap.tr("Visible Columns"));
jmTable.setIcon(XNapFrame.getSmallIcon("view_detailed.png"));
// FIX: the table model should contain static column identifier
SearchTableModel stm = new SearchTableModel();
jmTable.add(stm.createJMenu());
stm = new BrowseTableModel();
jmTable.add(stm.createJMenu());
jmTable.add(libraryPanel.getTableMenu());
jmTable.add(transferPanel.getDownloadTableMenu());
jmTable.add(transferPanel.getUploadTableMenu());
jmTable.add(apChat.getChannelTableMenu());
UserTableModel utm = new UserTableModel("user");
jmTable.add(utm.createJMenu());
settingsMenu.add(jmTable);
settingsMenu.addSeparator();
JMenu lfMenu = new JMenu(XNap.tr("Look & Feel"));
UIManager.LookAndFeelInfo[] info
= ThemeManager.getInstalledLookAndFeels();
ButtonGroup group = new ButtonGroup();
ActionListener lafListener = new LookAndFeelActionListener();
String currentLaf = UIManager.getLookAndFeel().getClass().getName();
for (int i = 0; i < info.length; i++) {
String look = info[i].getClassName();
JCheckBoxMenuItem item = new JCheckBoxMenuItem(info[i].getName());
item.setActionCommand(info[i].getClassName());
item.addActionListener(lafListener);
if (currentLaf.equals(info[i].getClassName())) {
item.setSelected(true);
}
group.add(item);
lfMenu.add(item);
}
settingsMenu.add(lfMenu);
settingsMenu.addSeparator();
JMenuItem jmiPreferences = new JMenuItem (new PreferencesAction());
settingsMenu.add(jmiPreferences);
jmiPreferences.setAccelerator
(KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.CTRL_MASK));
getJMenuBar().add(settingsMenu);
}
private void initializeHelpMenu()
{
JMenu helpMenu = new JMenu (XNap.tr("Help"));
JMenuItem check
= new JMenuItem(XNap.tr("Check For New Version") + "...");
check.addActionListener(this);
helpMenu.add(check);
JMenuItem jmiFaq = new JMenuItem (XNap.tr("Frequently Asked Questions") + "...");
jmiFaq.addActionListener(this);
helpMenu.add(jmiFaq);
JMenuItem jmiFeedback = new JMenuItem(XNap.tr("Send Feedback") + "...");
jmiFeedback.addActionListener(this);
helpMenu.add(jmiFeedback);
helpMenu.addSeparator();
JMenuItem jmiAbout = new JMenuItem (XNap.tr("About XNap") + "...");
jmiAbout.addActionListener(this);
helpMenu.add(jmiAbout);
getJMenuBar().add(helpMenu);
}
public static XNapFrame getInstance()
{
return singleton;
}
public static final ImageIcon getImage(String filename)
{
Preferences prefs = Preferences.getInstance();
URL url = FileHelper.getResource("icons/" + filename);
if (url != null && prefs.getShowIcons())
return new ImageIcon(url);
else
return null;
}
public static final ImageIcon getIcon(String filename)
{
return getImage("22/" + filename);
}
public static final Icon getEmptyIcon()
{
return new EmptyIcon(22);
}
public static final ImageIcon getSmallIcon(String filename)
{
return getImage("16/" + filename);
}
public static final Icon getSmallEmptyIcon()
{
return new EmptyIcon(16);
}
public static final ImageIcon getBigIcon(String filename)
{
return getImage("32/" + filename);
}
public static final Icon getBigEmptyIcon()
{
return new EmptyIcon(32);
}
public static final void setNextFocusPolicy(boolean focus)
{
focusExceptions++;
}
private static final boolean getFocusNextEvent()
{
if (focusExceptions > 0) {
focusExceptions--;
return !prefs.getFocusOnAllEvents();
}
else {
return prefs.getFocusOnAllEvents();
}
}
public static final void setFocusTo(String name)
{
if (getFocusNextEvent()) {
setFocusTo(getInstance().pane, name);
}
}
private static void setFocusTo(Container container, String name)
{
StringTokenizer t = new StringTokenizer(name, ".");
if (t.hasMoreTokens()) {
String find = t.nextToken();
Component[] c;
if (container instanceof ToggableIconPane) {
c = ((ToggableIconPane)container).getTabs();
}
else {
c = container.getComponents();
}
if (c == null) {
return;
}
for (int i = 0; i < c.length; i++) {
if (find.equals(c[i].getName())) {
if (container instanceof ToggableIconPane) {
((ToggableIconPane)container).setSelectedComponent(c[i]);
}
else if (container instanceof JTabbedPane) {
((JTabbedPane)container).setSelectedComponent(c[i]);
}
else {
c[i].requestFocus();
}
if (t.hasMoreTokens() && c[i] instanceof Container) {
setFocusTo((Container)c[i], t.nextToken(""));
}
return;
}
}
}
}
protected static class EmptyIcon implements Icon
{
private int size;
public EmptyIcon(int size)
{
this.size = size;
}
public int getIconHeight()
{
return size;
}
public int getIconWidth()
{
return size;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
}
}
public AbstractCommand[] getCommands()
{
return commands;
}
public void actionPerformed(ActionEvent e)
{
String a = e.getActionCommand();
if (e.getSource() instanceof JMenuItem) {
if (a.equals(XNap.tr("Exit"))) {
doExit();
}
else if (a.equals(XNap.tr("Setup Wizard") + "...")) {
StartupWizardDialog.showDialog(this, false);
}
else if (a.equals(XNap.tr("Console"))) {
ConsoleDialog.showDialog(this);
}
else if (a.equals(XNap.tr("Send Feedback") + "...")) {
FeedbackDialog.showDialog(this);
}
else if (a.equals(XNap.tr("About XNap") + "...")) {
doShowAbout();
}
else if (a.equals(XNap.tr("Check For New Version") + "...")) {
checkForUpdate(true);
}
else if (a.equals(XNap.tr("Frequently Asked Questions") + "...")) {
statusPanel.setText(XNap.tr("Downloading FAQ") + "...");
HTMLDialog.showDialog(this,
XNap.tr("Frequently Asked Questions"),
prefs.getFaqURL());
}
}
}
public void chatBlink()
{
if (pane.getSelectedComponent() != apChat) {
pane.blink(chatIndex, XNapFrame.getBigIcon("penguin.png"));
}
}
/**
* Updates the plugin menu. Selects or deselects the plugin checkbox.
*/
public void setEnabled(IPlugin plugin, boolean state)
{
JMenuItem jmi = (JMenuItem)pluginStateMenuItemByPlugin.get(plugin);
if (jmi != null) {
jmi.setSelected(state);
}
}
public void stateEnabled(StateEvent e)
{
if (e.getSource() instanceof IGUIPlugin) {
IGUIPlugin p = (IGUIPlugin)e.getSource();
JMenu menu = p.getMenu();
if (menu != null) {
menu.setEnabled(true);
}
JComponent panel = p.getPanel();
if (panel != null) {
if (panel instanceof JTabbedPane) {
((JTabbedPane)panel).addChangeListener
(XNapFrame.this);
}
// add item to view menu
JMenuItem jmi = new JMenuItem(p.getName());
jmi.addActionListener(viewListener);
viewMap.put(p.getName(), jmi);
viewMenu.add(jmi, PLUGIN_MENU_INDEX);
GUIHelper.setMnemonics(viewMenu.getPopupMenu());
// insert pane
pane.insertTab(p.getName(), p.getIcon(), panel, "",
PLUGIN_MENU_INDEX);
chatIndex++;
}
JComponent jcStatus = p.getStatusPanel();
if (jcStatus != null) {
jpStatus.add(jcStatus, PLUGIN_STATUS_PANEL_INDEX);
}
p.setStatusListener(XNapFrame.this);
}
setEnabled((IPlugin)e.getSource(), true);
}
/**
* Takes care of gui if plugin is disabled.
*/
public void stateDisabled(StateEvent e)
{
if (e.getSource() instanceof IGUIPlugin) {
IGUIPlugin p = (IGUIPlugin)e.getSource();
JMenu menu = p.getMenu();
if (menu != null) {
menu.setEnabled(false);
}
JComponent panel = p.getPanel();
if (panel != null) {
if (panel instanceof JTabbedPane) {
((JTabbedPane)panel).removeChangeListener
(XNapFrame.this);
}
JMenuItem jmi = (JMenuItem)viewMap.remove(p.getName());
viewMenu.remove(jmi);
pane.remove(panel);
chatIndex--;
}
JComponent statusPanel = p.getStatusPanel();
if (statusPanel != null) {
jpStatus.remove(statusPanel);
}
}
setEnabled((IPlugin)e.getSource(), false);
}
public void propertyChange(PropertyChangeEvent e)
{
String p = e.getPropertyName();
if (e.getSource() == prefs) {
if (p.equals("lookAndFeel")) {
// FIX ME
// updating the look and feel seems to break all Swing actions
// and the ToggableIconPane
//updateLookAndFeel();
}
// else if (p.equals("useSocksProxy")) {
// jmiUseSocksProxy.setSelected(prefs.getUseSocksProxy());
// }
else if (p.equals("useTabbedPane")) {
jmiUseTabbedPane.setSelected(prefs.getUseTabbedPane());
}
else if (p.equals("useTabbedTransferPane")) {
jmiUseTabbedTransferPane.setSelected
(prefs.getUseTabbedTransferPane());
}
else if (p.equals("sendChatAwayMessage")) {
jmiChatAway.setSelected(prefs.getSendChatAwayMessage());
}
}
}
private void checkForUpdate(boolean force)
{
if (force || prefs.shouldCheckForUpdate(7)) {
statusPanel.setText(XNap.tr("Checking for new version") + "...");
UpdateDialog.showDialog(this, force);
}
}
/**
* Closes XNap.
*/
public void doExit(boolean showCloseDialog)
{
if (showCloseDialog && !Dialogs.showCloseDialog(this)) {
return;
}
// save menu state
prefs.setShowCmdlToolbar(acShowCmdlToolbar.isVisible());
prefs.setShowMainToolbar(acShowMainToolbar.isVisible());
// save gui
ecbCmdl.writeHistoryFile(new File(CMD_HISTORY_FILENAME));
searchPanel.savePrefs();
transferPanel.savePrefs();
apChat.savePrefs();
apHotlist.savePrefs();
libraryPanel.savePrefs();
// save window positions
// it seems that XNap shrinks on every launch
prefs.setWindowHeight(getBounds().getSize().height
+ prefs.getCorrectivePixels());
prefs.setWindowWidth(getBounds().getSize().width);
prefs.setWindowX(getBounds().getLocation().x);
prefs.setWindowY(getBounds().getLocation().y);
// save plugin states
prefs.setEnabledGUIPlugins
(GUIPluginManager.getInstance().disablePlugins());
prefs.write();
// FIX: this should be placed elsewhere
UserManager.getInstance().write();
DownloadQueue.getInstance().stopAll();
UploadQueue.getInstance().stopAll();
// hide window to fake shutdown
dispose();
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
};
System.exit(0);
}
public void doExit()
{
doExit(prefs.getShowCloseDialog());
}
public void doShowAbout()
{
AboutDialog.showDialog(this);
}
public void doShowPreferences()
{
PreferencesDialog.showDialog(XNapFrame.this);
}
private void updateLookAndFeel()
{
try{
ThemeManager.setTheme(prefs.getTheme());
UIManager.setLookAndFeel(prefs.getLookAndFeel());
SwingUtilities.updateComponentTreeUI(this);
}
catch (Exception e) {
}
}
public void setStatus(String message)
{
statusPanel.setText(message);
}
public void stateChanged(ChangeEvent e)
{
Object source = pane.getSelectedComponent();
// remove pervious panel icons
while (jtbMain.getComponentCount() > tbCount) {
jtbMain.remove(jtbMain.getComponentCount() - 1);
}
if (source instanceof JTabbedPane) {
source = ((JTabbedPane)source).getSelectedComponent();
}
else if (source == apChat) {
if (pane.getSelectedComponent() != apChat) {
return;
}
// FIX: the source of the event is set to apChat instaead of
// jtp (which is a member of apChat). Java bug?
source = apChat.getSelectedTab();
}
if (source instanceof ActionSupport) {
AbstractAction[] actions = ((ActionSupport)source).getActions();
if (actions != null) {
for (int i = 0; i < actions.length; i++) {
if (actions[i] != null) {
jtbMain.add(actions[i]);
}
else {
jtbMain.addSeparator();
}
}
}
}
jtbMain.updateUI();
}
public void setVisible(boolean b)
{
super.setVisible(b);
if (b) {
GUINotifier.getGUIInstance().setGUIVisible(this, true);
}
}
/*
private void addIcons() {
AbstractPanel[] panels = {
searchPanel, statsPanel,
transferPanel
};
for (int i = 0; i < panels.length; i++) {
Debug.log(panels[i]);
AbstractAction[] actions = panels[i].getActions();
for (int j = 0; j < actions.length; j++) {
if (actions[j] != null)
jtbMain.add(actions[j]);
else
jtbMain.addSeparator();
}
jtbMain.addSeparator();
}
}
*/
/**
*
*/
private class ChatAwayAction extends AbstractAction
{
public ChatAwayAction()
{
putValue(Action.NAME, XNap.tr("Away"));
//putValue(Action.SMALL_ICON, XNapFrame.getIcon("configure.png"));
putValue(Action.SHORT_DESCRIPTION, XNap.tr("Send away message when people want to chat with me"));
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem)event.getSource();
prefs.setSendChatAwayMessage(jmi.isSelected());
}
}
}
/**
*
*/
private class CmdlAction extends AbstractAction
{
public CmdlAction()
{
putValue(Action.NAME, XNap.tr("Run"));
putValue(Action.SMALL_ICON, XNapFrame.getSmallIcon("exec.png"));
putValue(Action.SHORT_DESCRIPTION, XNap.tr("Runs Command"));
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_R));
}
public void actionPerformed(ActionEvent event)
{
String cmd = ecbCmdl.getText();
Executer.parseCommand(cmd);
ecbCmdl.addDistinctItemAtTop(cmd);
ecbCmdl.setText("");
}
}
/**
*
*/
private class InstallPluginsAction extends AbstractAction
{
public InstallPluginsAction()
{
putValue(Action.NAME, XNap.tr("Install") + "...");
putValue(Action.SMALL_ICON, XNapFrame.getIcon("configure.png"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Installs new plugins"));
}
public void actionPerformed(ActionEvent event)
{
PluginDialog.showDialog(XNapFrame.this);
}
}
/**
*
*/
private class PreferencesAction extends AbstractAction
{
public PreferencesAction()
{
putValue(Action.NAME, XNap.tr("Preferences") + "...");
putValue(Action.SMALL_ICON, XNapFrame.getIcon("configure.png"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Shows preferences dialog"));
}
public void actionPerformed(ActionEvent event)
{
doShowPreferences();
}
}
/**
*
*/
private class PurgeHistoryAction extends AbstractAction
{
public PurgeHistoryAction()
{
putValue(Action.NAME, XNap.tr("Clear All Histories"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Clear all histories."));
}
public void actionPerformed(ActionEvent event)
{
searchPanel.purgeHistory();
libraryPanel.purgeHistory();
}
}
/**
*
*/
private class ShowToolbarAction extends AbstractAction
{
private JToolBar jtb;
private boolean visible;
public ShowToolbarAction(JToolBar jtb, boolean visible)
{
this.jtb = jtb;
putValue(Action.NAME, jtb.getName());
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Show or hide toolbar"));
setVisible(visible);
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem)event.getSource();
setVisible(jmi.isSelected());
}
}
public void setVisible(boolean newValue)
{
this.visible = newValue;
jtb.setVisible(visible);
}
public boolean isVisible()
{
return visible;
}
}
/**
*
*/
private class UpdateRepositoryAction extends AbstractAction
{
public UpdateRepositoryAction()
{
putValue(Action.NAME, XNap.tr("Update Library"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Updates the library"));
}
public void actionPerformed(ActionEvent event)
{
Repository.getInstance().updateLater();
}
}
/**
*
*/
private class UseSocksProxyAction extends AbstractAction
{
public UseSocksProxyAction()
{
putValue(Action.NAME, XNap.tr("Use Socks Proxy"));
//putValue(Action.SMALL_ICON, XNapFrame.getIcon("configure.png"));
putValue(Action.SHORT_DESCRIPTION, XNap.tr("Enable socks proxy"));
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem)event.getSource();
prefs.setUseSocksProxy(jmi.isSelected());
prefs.write();
}
}
}
private class UseTabbedPaneAction extends AbstractAction
{
public UseTabbedPaneAction()
{
putValue(Action.NAME, XNap.tr("Use TabbedPane"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Use TabbedPane as main view"));
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem)event.getSource();
prefs.setUseTabbedPane(jmi.isSelected());
prefs.write();
pane.setUseTabbedPane(jmi.isSelected());
}
}
}
private class UseTabbedTransferPaneAction extends AbstractAction
{
public UseTabbedTransferPaneAction()
{
putValue(Action.NAME, XNap.tr("Use TabbedPane For Transfers"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Use TabbedPane as transfer view"));
}
public void actionPerformed(ActionEvent event)
{
if (event.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem)event.getSource();
prefs.setUseTabbedTransferPane(jmi.isSelected());
prefs.write();
}
}
}
private class PluginActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JMenuItem item = (JMenuItem)e.getSource();
PluginManager.getInstance().setEnabled
(e.getActionCommand(), item.isSelected());
}
}
/**
* Switches the panels if item is selected from view menu.
*/
private class ViewActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
pane.setSelectedComponent(e.getActionCommand());
}
}
private class LookAndFeelActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
prefs.setLookAndFeel(e.getActionCommand());
prefs.write();
Dialogs.showRestartNotification(XNapFrame.this);
}
}
private class WindowListener extends WindowAdapter
{
public void windowDeiconified(WindowEvent e)
{
if (wdi != null) {
wdi.hide();
}
}
public void windowIconified(WindowEvent e)
{
if (wdi != null) {
wdi.show("XNap");
wdi.hideFrame();
}
}
public void windowClosing (WindowEvent evt)
{
doExit();
}
}
protected class ExitCmd extends AbstractCommand
{
public ExitCmd()
{
putValue(CMD, new String[] {"exit", "quit", "q"});
putValue(SHORT_HELP, "Quits the application.");
}
public boolean execute(String[] argv)
{
doExit();
return true;
}
}
}