/** * Created on 04-Jun-2006 * Created by Allan Crooks * Copyright (C) 2006 Aelitis, All Rights Reserved. * * 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. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.ui.swt.mainwindow; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.*; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator; 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.Constants; import org.gudy.azureus2.core3.util.DisplayFormatters; import org.gudy.azureus2.ui.swt.Messages; import org.gudy.azureus2.ui.swt.shells.InputShell; import org.gudy.azureus2.ui.swt.shells.SpeedScaleShell; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreFactory; public class SelectableSpeedMenu { private final static int[] increases = { 1, 1, 3, 5, // totals 10 10, 40, // totals 50 50, // 100 50, 50, 100 }; public static void generateMenuItems(final Menu parent, final AzureusCore core, final GlobalManager globalManager, final boolean up_menu) { final MenuItem[] oldItems = parent.getItems(); for(int i = 0; i < oldItems.length; i++) { oldItems[i].dispose(); } final String configKey = up_menu? TransferSpeedValidator.getActiveUploadParameter(globalManager): "Max Download Speed KBs"; final int speedPartitions = 12; int maxBandwidth = COConfigurationManager.getIntParameter(configKey); final boolean unlim = (maxBandwidth == 0); maxBandwidth = adjustMaxBandWidth(maxBandwidth, globalManager, up_menu); boolean auto = false; if ( up_menu ){ final String configAutoKey = TransferSpeedValidator.getActiveAutoUploadParameter(globalManager); auto = COConfigurationManager.getBooleanParameter( configAutoKey ); // auto final MenuItem auto_item = new MenuItem(parent,SWT.CHECK); auto_item.setText(MessageText.getString("ConfigView.auto")); auto_item.addListener(SWT.Selection,new Listener() { public void handleEvent(Event e) { COConfigurationManager.setParameter(configAutoKey,auto_item.getSelection()); COConfigurationManager.save(); } }); if(auto)auto_item.setSelection(true); auto_item.setEnabled(TransferSpeedValidator.isAutoUploadAvailable(core)); new MenuItem(parent,SWT.SEPARATOR); } MenuItem item = new MenuItem(parent, SWT.RADIO); item.setText(MessageText.getString("MyTorrentsView.menu.setSpeed.unlimited")); item.setData("maxkb", new Integer(0)); item.setSelection(unlim && !auto); item.addListener(SWT.Selection, getLimitMenuItemListener(up_menu, parent, globalManager, configKey)); Integer[] speed_limits = null; final String config_prefix = "config.ui.speed.partitions.manual." + ((up_menu) ? "upload": "download") + "."; if (COConfigurationManager.getBooleanParameter(config_prefix + "enabled", false)) { speed_limits = parseSpeedPartitionString(COConfigurationManager.getStringParameter(config_prefix + "values", "")); } if (speed_limits == null) { speed_limits = getGenericSpeedList(speedPartitions, maxBandwidth); } for (int i=0; i<speed_limits.length; i++) { Integer i_value = speed_limits[i]; int value = i_value.intValue(); if (value < 5) {continue;} // Don't allow the user to easily select slow speeds. item = new MenuItem(parent, SWT.RADIO); item.setText(DisplayFormatters.formatByteCountToKiBEtcPerSec(value * 1024, true)); item.setData("maxkb", i_value); item.addListener(SWT.Selection, getLimitMenuItemListener(up_menu, parent, globalManager, configKey)); item.setSelection(!unlim && value == maxBandwidth && !auto); } new MenuItem(parent, SWT.SEPARATOR); final MenuItem itemDownSpeedManual = new MenuItem(parent, SWT.PUSH); Messages.setLanguageText(itemDownSpeedManual, "MyTorrentsView.menu.manual"); itemDownSpeedManual.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { String kbps_str = MessageText.getString("MyTorrentsView.dialog.setNumber.inKbps", new String[]{ DisplayFormatters.getRateUnit(DisplayFormatters.UNIT_KB ) }); InputShell is = new InputShell( "MyTorrentsView.dialog.setSpeed.title", new String[] { MessageText.getString(up_menu?"MyTorrentsView.dialog.setNumber.upload":"MyTorrentsView.dialog.setNumber.download") }, "MyTorrentsView.dialog.setNumber.text", new String[] { kbps_str, MessageText.getString(up_menu?"MyTorrentsView.dialog.setNumber.upload":"MyTorrentsView.dialog.setNumber.download") }); String sReturn = is.open(); if (sReturn == null) return; int newSpeed; try { newSpeed = (int) (Double.valueOf(sReturn).doubleValue()); } catch (NumberFormatException er) { MessageBox mb = new MessageBox(parent.getShell(), SWT.ICON_ERROR | SWT.OK); mb.setText(MessageText .getString("MyTorrentsView.dialog.NumberError.title")); mb.setMessage(MessageText .getString("MyTorrentsView.dialog.NumberError.text")); mb.open(); return; } if ( up_menu ){ } if ( up_menu ){ String configAutoKey = TransferSpeedValidator.getActiveAutoUploadParameter(globalManager); COConfigurationManager.setParameter( configAutoKey, false ); } final int cValue = ((Integer)new TransferSpeedValidator(configKey, new Integer(newSpeed)).getValue()).intValue(); COConfigurationManager.setParameter(configKey, cValue); COConfigurationManager.save(); } }); } /** * @param configKey * @return * * @since 3.0.1.7 */ private static int adjustMaxBandWidth(int maxBandwidth, GlobalManager globalManager, boolean up_menu) { if(maxBandwidth == 0 && !up_menu ) { GlobalManagerStats stats = globalManager.getStats(); int dataReceive = stats.getDataReceiveRate(); if (dataReceive < 1024) { maxBandwidth = 275; } else { maxBandwidth = dataReceive / 1024; } } return maxBandwidth; } private static java.util.Map parseSpeedPartitionStringCache = new java.util.HashMap(); private synchronized static Integer[] parseSpeedPartitionString(String s) { Integer[] result = (Integer[])parseSpeedPartitionStringCache.get(s); if (result == null) { try {result = parseSpeedPartitionString0(s);} catch (NumberFormatException nfe) {result = new Integer[0];} parseSpeedPartitionStringCache.put(s, result); } if (result.length == 0) {return null;} else {return result;} } private static Integer[] parseSpeedPartitionString0(String s) { java.util.StringTokenizer tokeniser = new java.util.StringTokenizer(s.trim(), ","); java.util.TreeSet values = new java.util.TreeSet(); // Filters duplicates out and orders the values. while (tokeniser.hasMoreTokens()) { values.add(new Integer(Integer.parseInt(tokeniser.nextToken().trim()))); } return (Integer[])values.toArray(new Integer[values.size()]); } /** * Gets the selection listener of a upload or download limit menu item (including unlimited) * @param parent The parent menu * @param configKey The configuration key * @return The selection listener */ private static final Listener getLimitMenuItemListener(final boolean up_menu, final Menu parent, final GlobalManager globalManager, final String configKey) { return new Listener() { public void handleEvent(Event event) { final MenuItem[] items = parent.getItems(); for(int i = 0; i < items.length; i++) { if(items[i] == event.widget) { items[i].setSelection(true); // turn off auto speed first as this will revert the upload limit to // what it was before it was turned on if ( up_menu ){ String configAutoKey = TransferSpeedValidator.getActiveAutoUploadParameter(globalManager); COConfigurationManager.setParameter( configAutoKey, false ); } final int cValue = ((Integer)new TransferSpeedValidator(configKey, (Number)items[i].getData("maxkb")).getValue()).intValue(); COConfigurationManager.setParameter(configKey, cValue); COConfigurationManager.save(); } else { items[i].setSelection(false); } } } }; } public static Integer[] getGenericSpeedList(int speedPartitions, int maxBandwidth) { java.util.List l = new java.util.ArrayList(); int delta = 0; int increaseLevel = 0; for (int i = 0; i < speedPartitions; i++) { final int[] valuePair; if (delta == 0) { valuePair = new int[] { maxBandwidth }; } else { valuePair = new int[] { maxBandwidth - delta * (maxBandwidth <= 1024 ? 1 : 1024), maxBandwidth + delta * (maxBandwidth < 1024 ? 1 : 1024) }; } for (int j = 0; j < valuePair.length; j++) { if (j == 0) { l.add(0, new Integer(valuePair[j])); } else { l.add(new Integer(valuePair[j])); } } delta += increases[increaseLevel]; if (increaseLevel < increases.length - 1) { increaseLevel++; } } return (Integer[]) l.toArray(new Integer[l.size()]); } /** * @since 3.0.1.7 */ public static void invokeSlider(boolean isUpSpeed) { final String prefix = MessageText.getString(isUpSpeed ? "GeneralView.label.maxuploadspeed" : "GeneralView.label.maxdownloadspeed"); GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager(); final String configAutoKey = TransferSpeedValidator.getActiveAutoUploadParameter(gm); boolean auto = COConfigurationManager.getBooleanParameter(configAutoKey); final String configKey = isUpSpeed ? TransferSpeedValidator.getActiveUploadParameter(gm) : "Max Download Speed KBs"; int maxBandwidth = COConfigurationManager.getIntParameter(configKey); final boolean unlim = (maxBandwidth == 0); if (unlim && !isUpSpeed) { GlobalManagerStats stats = gm.getStats(); int dataReceive = stats.getDataReceiveRate(); if (dataReceive >= 1024) { maxBandwidth = dataReceive / 1024; } } SpeedScaleShell speedScale = new SpeedScaleShell() { public String getStringValue(int value, String sValue) { if (sValue != null) { return prefix + ": " + sValue; } if (value == 0) { return MessageText.getString("MyTorrentsView.menu.setSpeed.unlimited"); } if (value == -1) { return MessageText.getString("ConfigView.auto"); } return prefix + ": " + (value == 0 ? MessageText.getString("ConfigView.unlimited") : DisplayFormatters.formatByteCountToKiBEtcPerSec( getValue() * 1024, true)); } }; int max = unlim ? (isUpSpeed ? 100 : 800) : maxBandwidth * 5; if (max < 50) { max = 50; } speedScale.setMaxValue(max); speedScale.setMaxTextValue(9999999); final String config_prefix = "config.ui.speed.partitions.manual." + (isUpSpeed ? "upload" : "download") + "."; int lastValue = COConfigurationManager.getIntParameter(config_prefix + "last", -10); Integer[] speed_limits; if (COConfigurationManager.getBooleanParameter(config_prefix + "enabled", false)) { speed_limits = parseSpeedPartitionString(COConfigurationManager.getStringParameter( config_prefix + "values", "")); } else { speed_limits = getGenericSpeedList(6, maxBandwidth); } if (speed_limits != null) { for (int i = 0; i < speed_limits.length; i++) { int value = speed_limits[i].intValue(); if (value > 0) { speedScale.addOption(DisplayFormatters.formatByteCountToKiBEtcPerSec( value * 1024, true), value); if (value == lastValue) { lastValue = -10; } } } } speedScale.addOption( MessageText.getString("MyTorrentsView.menu.setSpeed.unlimited"), 0); speedScale.addOption(MessageText.getString("ConfigView.auto"), -1); if (lastValue > 0) { speedScale.addOption(DisplayFormatters.formatByteCountToKiBEtcPerSec( lastValue * 1024, true), lastValue); } // SWT BUG: on windows/linux, if mouse is down on shell open, all mouse events // will not reflect this if (speedScale.open(auto ? -1 : maxBandwidth, Constants.isWindows || Constants.isLinux)) { int value = speedScale.getValue(); if (!speedScale.wasMenuChosen() || lastValue == value) { COConfigurationManager.setParameter(config_prefix + "last", maxBandwidth); } if (value >= 0) { if (auto) { COConfigurationManager.setParameter(configAutoKey, false); } COConfigurationManager.setParameter(configKey, value); COConfigurationManager.save(); } else { // autospeed COConfigurationManager.setParameter(configAutoKey, true); COConfigurationManager.save(); } } } }