/* * File : SystemTraySWT.java * Created : 2 avr. 2004 * By : Olivier * * Azureus - a Java Bittorrent client * * 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. * * 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 ( see the LICENSE file ). * * 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 org.gudy.azureus2.ui.systray; import java.util.List; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Tray; import org.eclipse.swt.widgets.TrayItem; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.download.DownloadManager; import org.gudy.azureus2.core3.global.GlobalManager; import org.gudy.azureus2.core3.global.GlobalManagerStats; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.util.AERunnable; import org.gudy.azureus2.core3.util.Constants; import org.gudy.azureus2.core3.util.DisplayFormatters; import org.gudy.azureus2.core3.util.SystemTime; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.ui.common.util.MenuItemManager; import org.gudy.azureus2.ui.swt.ImageRepository; import org.gudy.azureus2.ui.swt.MenuBuildUtils; import org.gudy.azureus2.ui.swt.Messages; import org.gudy.azureus2.ui.swt.Utils; import org.gudy.azureus2.ui.swt.mainwindow.MainWindow; import org.gudy.azureus2.ui.swt.mainwindow.SWTThread; import org.gudy.azureus2.ui.swt.mainwindow.SelectableSpeedMenu; import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT; import com.aelitis.azureus.ui.swt.UIFunctionsSWT; public class SystemTraySWT { Display display; UIFunctionsSWT uiFunctions; Tray tray; TrayItem trayItem; Menu menu; Image trayIconNormal = null, trayIconNotify = null; public SystemTraySWT() { System.out.println("****** our systray"); uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT(); display = SWTThread.getInstance().getDisplay(); tray = display.getSystemTray(); trayItem = new TrayItem(tray, SWT.NULL); if (!Constants.isOSX) { // trayItem.setImage(ImageRepository.getImage("azureus")); trayIconNormal = ImageRepository.getImage("azureus"); } else { // trayItem.setImage(ImageRepository.getImage("azureus_grey")); trayIconNormal = ImageRepository.getImage("azureus_grey"); } try { trayIconNotify = ImageRepository.getImage("trayicon_notify"); } catch (Exception e) { e.printStackTrace(); } trayItem.setImage(trayIconNormal); trayItem.setVisible(true); menu = new Menu(uiFunctions.getMainShell(), SWT.POP_UP); menu.addMenuListener(new MenuListener() { public void menuShown(MenuEvent _menu) { } public void menuHidden(MenuEvent _menu) { if (Constants.isOSX) { trayItem.setImage(ImageRepository.getImage("azureus_grey")); } } }); MenuBuildUtils.addMaintenanceListenerForMenu(menu, new MenuBuildUtils.MenuBuilder() { public void buildMenu(Menu menu) { fillMenu(menu); } }); trayItem.addListener(SWT.DefaultSelection, new Listener() { public void handleEvent(Event arg0) { showMainWindow(); } }); trayItem.addListener(SWT.Selection, new Listener() { long lastTime = 0; public void handleEvent(Event arg0) { // Bug in Windows (seems to have started around SWT 3.3 Release // Candidates) where double click isn't interpreted as DefaultSelection // Since we "know" SWT.Selection is actually a mouse down, check // if two mouse downs happen in a short timespan and fake a // DefaultSelection if (Constants.isWindows) { long now = SystemTime.getCurrentTime(); if (now - lastTime < 200) { showMainWindow(); } else { lastTime = now; } } else if (Constants.isOSX) { trayItem.setImage(ImageRepository.getImage("azureus_white")); menu.setVisible(true); } } }); trayItem.addListener(SWT.MenuDetect, new Listener() { public void handleEvent(Event arg0) { menu.setVisible(true); } }); } public void fillMenu(final Menu menu) { final MenuItem itemShow = new MenuItem(menu, SWT.NULL); //Messages.setLanguageText(itemShow, "SystemTray.menu.show"); itemShow.setText("Show OneSwarm..."); new MenuItem(menu, SWT.SEPARATOR); // final MenuItem itemCloseAll = new MenuItem(menu, SWT.NULL); // Messages.setLanguageText(itemCloseAll, // "SystemTray.menu.closealldownloadbars"); // // final MenuItem itemShowGlobalTransferBar = new MenuItem(menu, SWT.CHECK); // Messages.setLanguageText(itemShowGlobalTransferBar, // "SystemTray.menu.open_global_transfer_bar"); // // new MenuItem(menu, SWT.SEPARATOR); org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items; menu_items = MenuItemManager.getInstance().getAllAsArray("systray"); if (menu_items.length > 0) { MenuBuildUtils.addPluginMenuItems(uiFunctions.getMainShell(), menu_items, menu, true, true, MenuBuildUtils.BASIC_MENU_ITEM_CONTROLLER); new MenuItem(menu, SWT.SEPARATOR); } createUploadLimitMenu(menu); createDownloadLimitMenu(menu); /* * if we are running on windows: */ if (Constants.isWindows) { new MenuItem(menu, SWT.SEPARATOR); final MenuItem startWithWindowsCheckbox = new MenuItem(menu, SWT.CHECK); startWithWindowsCheckbox.setText("Start with Windows"); startWithWindowsCheckbox.setSelection(COConfigurationManager.getBooleanParameter("autostart")); startWithWindowsCheckbox.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent arg0) { if (COConfigurationManager.getBooleanParameter("autostart")) { COConfigurationManager.setParameter("autostart", false); } else { COConfigurationManager.setParameter("autostart", true); } } public void widgetDefaultSelected(SelectionEvent arg0) { } }); } new MenuItem(menu, SWT.SEPARATOR); final MenuItem itemStartAll = new MenuItem(menu, SWT.NULL); Messages.setLanguageText(itemStartAll, "SystemTray.menu.startalltransfers"); final MenuItem itemStopAll = new MenuItem(menu, SWT.NULL); Messages.setLanguageText(itemStopAll, "SystemTray.menu.stopalltransfers"); final MenuItem itemPause = new MenuItem(menu, SWT.NULL); Messages.setLanguageText(itemPause, "SystemTray.menu.pausetransfers"); final MenuItem itemResume = new MenuItem(menu, SWT.NULL); Messages.setLanguageText(itemResume, "SystemTray.menu.resumetransfers"); new MenuItem(menu, SWT.SEPARATOR); final MenuItem itemOldUI = new MenuItem(menu, SWT.NULL); itemOldUI.setText("Show Classic UI"); itemOldUI.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { MainWindow.forceShowForOldUI(); } }); itemShow.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { showMainWindow(); } }); itemStartAll.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { AzureusCoreFactory.getSingleton().getGlobalManager().startAllDownloads(); } }); itemStopAll.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { ManagerUtils.asyncStopAll(); } }); itemPause.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { ManagerUtils.asyncPause(); } }); itemResume.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { AzureusCoreFactory.getSingleton().getGlobalManager().resumeDownloads(); } }); if (Constants.isOSX == false) { new MenuItem(menu, SWT.SEPARATOR); final MenuItem itemExit = new MenuItem(menu, SWT.NULL); Messages.setLanguageText(itemExit, "SystemTray.menu.exit"); itemExit.addListener(SWT.Selection, new Listener() { public void handleEvent(Event arg0) { uiFunctions.requestShutdown(); } }); } GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager(); itemPause.setEnabled(gm.canPauseDownloads()); itemResume.setEnabled(gm.canResumeDownloads()); // itemCloseAll.addListener(SWT.Selection, new Listener() { // public void handleEvent(Event arg0) { // uiFunctions.closeDownloadBars(); // } // }); // // itemShowGlobalTransferBar.setSelection(uiFunctions.isGlobalTransferBarShown()); // itemShowGlobalTransferBar.addListener(SWT.Selection, new Listener() { // public void handleEvent(Event arg0) { // if (uiFunctions.isGlobalTransferBarShown()) { // uiFunctions.closeGlobalTransferBar(); // } // else { // uiFunctions.showGlobalTransferBar(); // } // } // }); } /** * Creates the global upload limit context menu item * @param parent The system tray contextual menu */ private final void createUploadLimitMenu(final Menu parent) { final MenuItem uploadSpeedItem = new MenuItem(parent, SWT.CASCADE); uploadSpeedItem.setText(MessageText.getString("GeneralView.label.maxuploadspeed")); final Menu uploadSpeedMenu = new Menu(uiFunctions.getMainShell(), SWT.DROP_DOWN); uploadSpeedMenu.addListener(SWT.Show, new Listener() { public void handleEvent(Event event) { AzureusCore core = AzureusCoreFactory.getSingleton(); SelectableSpeedMenu.generateMenuItems(uploadSpeedMenu, core, core.getGlobalManager(), true); } }); uploadSpeedItem.setMenu(uploadSpeedMenu); } /** * Creates the global download limit context menu item * @param parent The system tray contextual menu */ private final void createDownloadLimitMenu(final Menu parent) { final MenuItem downloadSpeedItem = new MenuItem(parent, SWT.CASCADE); downloadSpeedItem.setText(MessageText.getString("GeneralView.label.maxdownloadspeed")); final Menu downloadSpeedMenu = new Menu(uiFunctions.getMainShell(), SWT.DROP_DOWN); downloadSpeedMenu.addListener(SWT.Show, new Listener() { public void handleEvent(Event event) { AzureusCore core = AzureusCoreFactory.getSingleton(); SelectableSpeedMenu.generateMenuItems(downloadSpeedMenu, core, core.getGlobalManager(), false); } }); downloadSpeedItem.setMenu(downloadSpeedMenu); } public void dispose() { Utils.execSWTThread(new AERunnable() { @Override public void runSupport() { if (trayItem != null && !trayItem.isDisposed()) { trayItem.dispose(); } } }); } ClassLoader mF2FClassLoader = null; public void update() { if (trayItem.isDisposed()) return; List managers = AzureusCoreFactory.getSingleton().getGlobalManager().getDownloadManagers(); //StringBuffer toolTip = new StringBuffer("Azureus - ");//$NON-NLS-1$ StringBuffer toolTip = new StringBuffer(); int seeding = 0; int downloading = 0; for (int i = 0; i < managers.size(); i++) { DownloadManager manager = (DownloadManager) managers.get(i); int state = manager.getState(); if (state == DownloadManager.STATE_DOWNLOADING) downloading++; if (state == DownloadManager.STATE_SEEDING) seeding++; } /** * If we've loaded the F2F plugin, get the number of unread messages and add this to the tooltip */ if (mF2FClassLoader == null) { PluginInterface f2fInterface = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID( "osf2f"); if (f2fInterface != null) { if (f2fInterface.isOperational()) { mF2FClassLoader = f2fInterface.getPluginClassLoader(); } else { ; } } } if (mF2FClassLoader != null) { try { Class chatClass = Class.forName("edu.washington.cs.oneswarm.f2f.chat.ChatDAO"); Object chatInstance = chatClass.getMethod("get").invoke(null); Map<String, Integer> unread = (Map<String, Integer>) chatClass.getMethod( "getUnreadMessageCounts").invoke(chatInstance); int count = 0; for (Integer v : unread.values()) { count += v; } if (count > 0) { toolTip.append(MessageText.getString( "SystemTray.tooltip.chatmessages").replaceAll("%1", "" + count) + "\n"); if (trayItem.getImage() != trayIconNotify && trayIconNotify != null) { trayItem.setImage(trayIconNotify); } } else if (trayItem.getImage() != trayIconNormal) { trayItem.setImage(trayIconNormal); } } catch (Exception e) { e.printStackTrace(); mF2FClassLoader = null; } } // something went funny here across Java versions, leading " " got lost String seeding_text = MessageText.getString("SystemTray.tooltip.seeding").replaceAll( "%1", "" + seeding); String downloading_text = MessageText.getString( "SystemTray.tooltip.downloading").replaceAll("%1", "" + downloading); /* if ( !seeding_text.startsWith(" " )){ seeding_text = " " + seeding_text; }*/ if (!downloading_text.startsWith(" ")) { downloading_text = " " + downloading_text; } GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager(); GlobalManagerStats stats = gm.getStats(); toolTip.append(seeding_text).append(downloading_text).append("\n"); toolTip.append(MessageText.getString("ConfigView.download.abbreviated")).append( " "); toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec( stats.getDataReceiveRate(), stats.getProtocolReceiveRate())); toolTip.append(", ").append( MessageText.getString("ConfigView.upload.abbreviated")).append(" "); toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec( stats.getDataSendRate(), stats.getProtocolSendRate())); trayItem.setToolTipText(toolTip.toString()); //Why should we refresh the image? it never changes ... //and is a memory bottleneck for some non-obvious reasons. //trayItem.setImage(ImageRepository.getImage("azureus")); trayItem.setVisible(true); } private void showMainWindow() { Utils.launch(Constants.ONESWARM_ENTRY_URL); } public void updateLanguage() { if (menu != null) { Messages.updateLanguageForControl(menu); } update(); } }