/*
* Created on 2 juil. 2003
*
* Copyright (C) 2004, 2005, 2006 Aelitis SAS, 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.
*
* 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
*
* 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.views;
import java.util.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
import org.gudy.azureus2.core3.download.DownloadManager;
import org.gudy.azureus2.core3.download.DownloadManagerStats;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.DisplayFormatters;
import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
import org.gudy.azureus2.ui.swt.Messages;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.components.Legend;
import org.gudy.azureus2.ui.swt.components.graphics.MultiPlotGraphic;
import org.gudy.azureus2.ui.swt.components.graphics.ValueFormater;
import org.gudy.azureus2.ui.swt.components.graphics.ValueSource;
import org.gudy.azureus2.ui.swt.mainwindow.Colors;
import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
import org.gudy.azureus2.ui.swt.plugins.UISWTView;
import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewEventImpl;
import com.aelitis.azureus.core.util.GeneralUtils;
import com.aelitis.azureus.core.util.average.MovingImmediateAverage;
import com.aelitis.azureus.ui.common.ToolBarItem;
import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
public class
DownloadActivityView
implements UISWTViewCoreEventListener, UIPluginViewToolBarListener
{
public static final String MSGID_PREFIX = "DownloadActivityView";
private static Color[] colors = {
Colors.fadedGreen, Colors.fadedGreen,
Colors.blues[Colors.BLUES_DARKEST], Colors.blues[Colors.BLUES_DARKEST],
Colors.light_grey };
private UISWTView swtView;
private boolean legend_at_bottom;
private Composite panel;
private MultiPlotGraphic mpg;
private DownloadManager manager;
public
DownloadActivityView()
{
}
private String
getFullTitle()
{
return( MessageText.getString(MSGID_PREFIX + ".title.full" ));
}
public void
initialize(
Composite composite )
{
panel = new Composite(composite,SWT.NULL);
panel.setLayout(new GridLayout(legend_at_bottom?1:2, false));
GridData gridData;
ValueFormater formatter =
new ValueFormater()
{
public String
format(
int value)
{
return DisplayFormatters.formatByteCountToKiBEtcPerSec( value );
}
};
final ValueSourceImpl[] sources = {
new ValueSourceImpl( "Up", 0, colors, true, false, false )
{
public int
getValue()
{
DownloadManager dm = manager;
if ( dm == null ){
return( 0 );
}
DownloadManagerStats stats = manager.getStats();
return((int)(stats.getDataSendRate()));
}
},
new ValueSourceImpl( "Up Smooth", 1, colors, true, false, true )
{
public int
getValue()
{
DownloadManager dm = manager;
if ( dm == null ){
return( 0 );
}
DownloadManagerStats stats = manager.getStats();
return((int)(stats.getSmoothedDataSendRate()));
}
},
new ValueSourceImpl( "Down", 2, colors, false, false, false )
{
public int
getValue()
{
DownloadManager dm = manager;
if ( dm == null ){
return( 0 );
}
DownloadManagerStats stats = manager.getStats();
return((int)(stats.getDataReceiveRate()));
}
},
new ValueSourceImpl( "Down Smooth", 3, colors, false, false, true )
{
public int
getValue()
{
DownloadManager dm = manager;
if ( dm == null ){
return( 0 );
}
DownloadManagerStats stats = manager.getStats();
return((int)(stats.getSmoothedDataReceiveRate()));
}
},
new ValueSourceImpl( "Swarm Peer Average", 4, colors, false, true, false )
{
public int
getValue()
{
DownloadManager dm = manager;
if ( dm == null ){
return( 0 );
}
return((int)(manager.getStats().getTotalAveragePerPeer()));
}
}
};
final MultiPlotGraphic f_mpg = mpg = MultiPlotGraphic.getInstance( sources, formatter );
String[] color_configs = new String[] {
"DownloadActivityView.legend.up",
"DownloadActivityView.legend.up_smooth",
"DownloadActivityView.legend.down",
"DownloadActivityView.legend.down_smooth",
"DownloadActivityView.legend.peeraverage",
};
Legend.LegendListener legend_listener =
new Legend.LegendListener()
{
private int hover_index = -1;
public void
hoverChange(
boolean entry,
int index )
{
if ( hover_index != -1 ){
sources[hover_index].setHover( false );
}
if ( entry ){
hover_index = index;
sources[index].setHover( true );
}
f_mpg.refresh( true );
}
public void
visibilityChange(
boolean visible,
int index )
{
sources[index].setVisible( visible );
f_mpg.refresh( true );
}
};
if ( !legend_at_bottom ){
gridData = new GridData( GridData.FILL_VERTICAL );
gridData.verticalAlignment = SWT.CENTER;
Legend.createLegendComposite(panel, colors, color_configs, null, gridData, false, legend_listener );
}
Composite gSpeed = new Composite(panel,SWT.NULL);
gridData = new GridData(GridData.FILL_BOTH);
gSpeed.setLayoutData(gridData);
gSpeed.setLayout(new GridLayout());
if ( legend_at_bottom ){
gridData = new GridData(GridData.FILL_HORIZONTAL);
Legend.createLegendComposite(panel, colors, color_configs, null, gridData, true, legend_listener );
}
Canvas speedCanvas = new Canvas(gSpeed,SWT.NO_BACKGROUND);
gridData = new GridData(GridData.FILL_BOTH);
speedCanvas.setLayoutData(gridData);
mpg.initialize( speedCanvas, false );
}
private void
refresh(
boolean force )
{
mpg.refresh( force );
}
public Composite
getComposite()
{
return( panel );
}
private boolean comp_focused;
private Object focus_pending_ds;
private void
setFocused( boolean foc )
{
if ( foc ){
comp_focused = true;
dataSourceChanged( focus_pending_ds );
}else{
focus_pending_ds = manager;
dataSourceChanged( null );
comp_focused = false;
}
}
public void
dataSourceChanged(
Object newDataSource )
{
if ( !comp_focused ){
focus_pending_ds = newDataSource;
return;
}
DownloadManager old_manager = manager;
if (newDataSource == null){
manager = null;
}else if (newDataSource instanceof Object[]){
Object temp = ((Object[])newDataSource)[0];
if ( temp instanceof DownloadManager ){
manager = (DownloadManager)temp;
}else if ( temp instanceof DiskManagerFileInfo){
manager = ((DiskManagerFileInfo)temp).getDownloadManager();
}else{
return;
}
}else{
if ( newDataSource instanceof DownloadManager ){
manager = (DownloadManager)newDataSource;
}else if ( newDataSource instanceof DiskManagerFileInfo){
manager = ((DiskManagerFileInfo)newDataSource).getDownloadManager();
}else{
return;
}
}
if ( old_manager == manager ){
return;
}
if ( manager == null ){
mpg.setActive( false );
mpg.reset( new int[5][0] );
}else{
DownloadManagerStats stats = manager.getStats();
stats.setRecentHistoryRetention( true );
int[][] _history = stats.getRecentHistory();
// reconstitute the smoothed values to the best of our ability (good enough unless we decide we want
// to throw more memory at remembering this more accurately...)
int[] send_history = _history[0];
int[] recv_history = _history[1];
int history_secs = send_history.length;
int[] smoothed_send = new int[history_secs];
int[] smoothed_recv = new int[history_secs];
MovingImmediateAverage send_average = GeneralUtils.getSmoothAverage();
MovingImmediateAverage recv_average = GeneralUtils.getSmoothAverage();
int smooth_interval = GeneralUtils.getSmoothUpdateInterval();
int current_smooth_send = 0;
int current_smooth_recv = 0;
int pending_smooth_send = 0;
int pending_smooth_recv = 0;
for ( int i=0;i<history_secs;i++){
pending_smooth_send += send_history[i];
pending_smooth_recv += recv_history[i];
if ( i % smooth_interval == 0 ){
current_smooth_send = (int)(send_average.update( pending_smooth_send )/smooth_interval);
current_smooth_recv = (int)(recv_average.update( pending_smooth_recv )/smooth_interval);
pending_smooth_send = 0;
pending_smooth_recv = 0;
}
smoothed_send[i] = current_smooth_send;
smoothed_recv[i] = current_smooth_recv;
}
int[][] history = {send_history, smoothed_send, recv_history, smoothed_recv, _history[2] };
mpg.reset( history );
mpg.setActive( true );
}
}
public void
delete()
{
Utils.disposeComposite( panel );
if ( mpg != null ){
mpg.dispose();
}
}
public boolean
eventOccurred(
UISWTViewEvent event )
{
switch( event.getType()){
case UISWTViewEvent.TYPE_CREATE:{
swtView = event.getView();
swtView.setTitle(getFullTitle());
swtView.setToolBarListener(this);
if ( event instanceof UISWTViewEventImpl ){
String parent = ((UISWTViewEventImpl)event).getParentID();
legend_at_bottom = parent != null && parent.equals( UISWTInstance.VIEW_TORRENT_DETAILS );
}
break;
}
case UISWTViewEvent.TYPE_DESTROY:{
delete();
break;
}
case UISWTViewEvent.TYPE_INITIALIZE:{
initialize((Composite)event.getData());
break;
}
case UISWTViewEvent.TYPE_REFRESH:{
refresh( false );
break;
}
case UISWTViewEvent.TYPE_LANGUAGEUPDATE:{
Messages.updateLanguageForControl(getComposite());
swtView.setTitle(getFullTitle());
break;
}
case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:{
dataSourceChanged(event.getData());
break;
}
case UISWTViewEvent.TYPE_FOCUSGAINED:{
String id = "DMDetails_DownloadGraph";
setFocused( true ); // do this here to pick up corrent manager before rest of code
if ( manager != null ){
if ( manager.getTorrent() != null ){
id += "." + manager.getInternalName();
}else{
id += ":" + manager.getSize();
}
}
SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[]{ new SelectedContent(manager)});
refresh( true );
break;
}
case UISWTViewEvent.TYPE_FOCUSLOST:{
setFocused( false );
break;
}
}
return( true );
}
public boolean
toolBarItemActivated(
ToolBarItem item,
long activationType,
Object datasource)
{
return( ViewUtils.toolBarItemActivated( manager, item, activationType, datasource ));
}
public void
refreshToolBarItems(
Map<String, Long> list)
{
ViewUtils.refreshToolBarItems(manager, list);
}
private abstract class
ValueSourceImpl
implements ValueSource
{
private String name;
private int index;
private Color[] colours;
private boolean is_up;
private boolean trimmable;
private boolean is_hover;
private boolean is_invisible;
private boolean is_dotted;
private
ValueSourceImpl(
String _name,
int _index,
Color[] _colours,
boolean _is_up,
boolean _trimmable,
boolean _is_dotted )
{
name = _name;
index = _index;
colours = _colours;
is_up = _is_up;
trimmable = _trimmable;
is_dotted = _is_dotted;
}
public String
getName()
{
return( name );
}
public Color
getLineColor()
{
return( colours[index] );
}
public boolean
isTrimmable()
{
return( trimmable );
}
private void
setHover(
boolean h )
{
is_hover = h;
}
private void
setVisible(
boolean visible )
{
is_invisible = !visible;
}
public int
getStyle()
{
if ( is_invisible ){
return( STYLE_INVISIBLE );
}
int style = is_up?STYLE_UP:STYLE_DOWN;
if ( is_hover ){
style |= STYLE_BOLD;
}
if ( is_dotted ){
style |= STYLE_HIDE_LABEL;
}
return( style );
}
public int
getAlpha()
{
return( is_dotted?128:255 );
}
}
}