FileDocCategorySizeDatePackage
PeerInfoView.javaAPI DocAzureus 3.0.3.417805Fri Jun 15 11:50:38 BST 2007org.gudy.azureus2.ui.swt.views.peer

PeerInfoView

public class PeerInfoView extends org.gudy.azureus2.ui.swt.views.AbstractIView implements org.gudy.azureus2.ui.swt.debug.ObfusticateImage
Piece Map subview for Peers View. Testing bed for SubView stuff.
author
TuxPaper
created
2005/10/02
todo
on paint, paint cached image instead of recalc

Fields Summary
private static final int
BLOCK_FILLSIZE
private static final int
BLOCK_SPACING
private static final int
BLOCK_SIZE
private static final int
BLOCKCOLOR_AVAIL_HAVE
private static final int
BLOCKCOLOR_AVAIL_NOHAVE
private static final int
BLOCKCOLOR_NOAVAIL_HAVE
private static final int
BLOCKCOLOR_NOAVAIL_NOHAVE
private static final int
BLOCKCOLOR_TRANSFER
private static final int
BLOCKCOLOR_NEXT
private static final int
BLOCKCOLOR_AVAILCOUNT
private Composite
peerInfoComposite
private org.eclipse.swt.custom.ScrolledComposite
sc
protected Canvas
peerInfoCanvas
private Color[]
blockColors
private Label
topLabel
private Label
imageLabel
private int
graphicsUpdate
private int
loopFactor
private org.gudy.azureus2.core3.peer.PEPeer
peer
private org.gudy.azureus2.plugins.Plugin
countryLocator
private String
sCountryImagesDir
private Font
font
Image
img
Constructors Summary
public PeerInfoView()
Initialize


	 	 
	  
		blockColors = new Color[] { Colors.blues[Colors.BLUES_DARKEST],
				Colors.blues[Colors.BLUES_MIDLIGHT], Colors.fadedGreen, Colors.white,
				Colors.red, Colors.fadedRed, Colors.black };

		// Pull in Country Information if the plugin exists
		/**
		 * If this view was a real plugin view, we could attach the CountryLocator.jar
		 * to our project, cast countryLocator as CountryLocator (instead of Plugin),
		 * and then directly call the functions.
		 * 
		 * Since we are in core, and we don't want to add a dependency on the
		 * CountryLocator.jar, we invoke the methods via the Class object.
		 */
		try {
			PluginInterface pi = PluginInitializer.getDefaultInterface()
					.getPluginManager().getPluginInterfaceByID("CountryLocator");
			if (pi != null) {
				countryLocator = pi.getPlugin();
				if (!pi.isOperational()
						|| pi.getUtilities().compareVersions(pi.getPluginVersion(), "1.6") < 0)
					countryLocator = null;

				if (countryLocator != null) {
					sCountryImagesDir = (String) countryLocator.getClass().getMethod(
							"getImageLocation", new Class[] { Integer.TYPE }).invoke(
							countryLocator, new Object[] { new Integer(0) });
				}
			}
		} catch (Throwable t) {

		}
	
Methods Summary
private CompositecreatePeerInfoPanel(Composite parent)

		GridLayout layout;
		GridData gridData;

		// Peer Info section contains
		// - Peer's Block display
		// - Peer's Datarate
		peerInfoComposite = new Composite(parent, SWT.NONE);
		layout = new GridLayout();
		layout.numColumns = 2;
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		peerInfoComposite.setLayout(layout);
		gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
		peerInfoComposite.setLayoutData(gridData);

		imageLabel = new Label(peerInfoComposite, SWT.NULL);
		gridData = new GridData();
		if (countryLocator != null)
			gridData.widthHint = 28;
		imageLabel.setLayoutData(gridData);

		topLabel = new Label(peerInfoComposite, SWT.NULL);
		gridData = new GridData(SWT.FILL, SWT.DEFAULT, false, false);
		topLabel.setLayoutData(gridData);

		sc = new ScrolledComposite(peerInfoComposite, SWT.V_SCROLL);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);
		layout = new GridLayout();
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		sc.setLayout(layout);
		gridData = new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1);
		sc.setLayoutData(gridData);
		sc.getVerticalBar().setIncrement(BLOCK_SIZE);

		peerInfoCanvas = new Canvas(sc, SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
		gridData = new GridData(GridData.FILL, SWT.DEFAULT, true, false);
		peerInfoCanvas.setLayoutData(gridData);
		peerInfoCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				if (e.width <= 0 || e.height <= 0)
					return;
				try {
					Rectangle bounds = (img == null) ? null : img.getBounds();
					if (bounds == null) {
						e.gc.fillRectangle(e.x, e.y, e.width, e.height);
					} else {
						if (e.x + e.width > bounds.width)
							e.gc.fillRectangle(bounds.width, e.y, e.x + e.width
									- bounds.width + 1, e.height);
						if (e.y + e.height > bounds.height)
							e.gc.fillRectangle(e.x, bounds.height, e.width, e.y + e.height
									- bounds.height + 1);

						int width = Math.min(e.width, bounds.width - e.x);
						int height = Math.min(e.height, bounds.height - e.y);
						e.gc.drawImage(img, e.x, e.y, width, height, e.x, e.y, width,
								height);
					}
				} catch (Exception ex) {
				}
			}
		});
		Listener doNothingListener = new Listener() {
			public void handleEvent(Event event) {
			}
		};
		peerInfoCanvas.addListener(SWT.KeyDown, doNothingListener);

		peerInfoCanvas.addListener(SWT.Resize, new Listener() {
			public void handleEvent(Event e) {
				// wrap in asyncexec because sc.setMinWidth (called later) doesn't work
				// too well inside a resize (the canvas won't size isn't always updated)
				e.widget.getDisplay().asyncExec(new AERunnable() {
					public void runSupport() {
						if (img != null) {
							int iOldColCount = img.getBounds().width / BLOCK_SIZE;
							int iNewColCount = peerInfoCanvas.getClientArea().width / BLOCK_SIZE;
							if (iOldColCount != iNewColCount)
								refreshInfoCanvas();
						}
					}
				});
			}
		});

		sc.setContent(peerInfoCanvas);

		Legend.createLegendComposite(peerInfoComposite,
				blockColors, new String[] { "PeersView.BlockView.Avail.Have",
						"PeersView.BlockView.Avail.NoHave",
						"PeersView.BlockView.NoAvail.Have",
						"PeersView.BlockView.NoAvail.NoHave",
						"PeersView.BlockView.Transfer", "PeersView.BlockView.NextRequest",
						"PeersView.BlockView.AvailCount" }, new GridData(SWT.FILL,
						SWT.DEFAULT, true, false, 2, 1));

		int iFontPixelsHeight = 10;
		int iFontPointHeight = (iFontPixelsHeight * 72)
				/ peerInfoCanvas.getDisplay().getDPI().y;
		Font f = peerInfoCanvas.getFont();
		FontData[] fontData = f.getFontData();
		fontData[0].setHeight(iFontPointHeight);
		font = new Font(peerInfoCanvas.getDisplay(), fontData);

		return peerInfoComposite;
	
public voiddataSourceChanged(java.lang.Object newDataSource)

		if (newDataSource == null)
			peer = null;
		else if (newDataSource instanceof Object[])
			peer = (PEPeer) ((Object[]) newDataSource)[0];
		else
			peer = (PEPeer) newDataSource;

		fillPeerInfoSection();
	
public voiddelete()

		if (!imageLabel.isDisposed() && imageLabel.getImage() != null) {
			Image image = imageLabel.getImage();
			imageLabel.setImage(null);
			image.dispose();
		}

		if (img != null && !img.isDisposed()) {
			img.dispose();
			img = null;
		}

		if (font != null && !font.isDisposed()) {
			font.dispose();
			font = null;
		}

		super.delete();
	
public voidfillPeerInfoSection()

		if (imageLabel.getImage() != null) {
			Image image = imageLabel.getImage();
			imageLabel.setImage(null);
			image.dispose();
		}

		if (peer == null) {
			topLabel.setText("");
		} else {
			String s = peer.getClient();
			if (s == null)
				s = "";
			if (s != "")
				s += "; ";

			s += peer.getIp()
					+ "; "
					+ DisplayFormatters.formatPercentFromThousands(peer
							.getPercentDoneInThousandNotation());
			topLabel.setText(s);

			if (countryLocator != null) {
				try {
					String sCountry = (String) countryLocator.getClass().getMethod(
							"getIPCountry", new Class[] { String.class, Locale.class })
							.invoke(countryLocator,
									new Object[] { peer.getIp(), Locale.getDefault() });

					String sCode = (String) countryLocator.getClass().getMethod(
							"getIPISO3166", new Class[] { String.class }).invoke(
							countryLocator, new Object[] { peer.getIp() });

					imageLabel.setToolTipText(sCode + "- " + sCountry);

					InputStream is = countryLocator.getClass().getClassLoader()
							.getResourceAsStream(
									sCountryImagesDir + "/" + sCode.toLowerCase() + ".png");
					if (is != null) {
						Image img = new Image(imageLabel.getDisplay(), is);
						img.setBackground(imageLabel.getBackground());
						imageLabel.setImage(img);
					}

				} catch (Exception e) {
					// ignore
				}
			}
		}
		refreshInfoCanvas();
	
public CompositegetComposite()

		return peerInfoComposite;
	
public java.lang.StringgetData()

		return "PeersView.BlockView.title";
	
public voidinitialize(Composite composite)

		if (peerInfoComposite != null && !peerInfoComposite.isDisposed()) {
			Logger.log(new LogEvent(LogIDs.GUI, LogEvent.LT_ERROR,
					"PeerInfoView already initialized! Stack: "
							+ Debug.getStackTrace(true, false)));
			delete();
		}
		createPeerInfoPanel(composite);
	
public ImageobfusticatedImage(Image image, Point shellOffset)

		UIDebugGenerator.obfusticateArea(image, topLabel, shellOffset, "");
		return image;
	
public voidrefresh()

		super.refresh();

		if (loopFactor++ % graphicsUpdate == 0) {
			refreshInfoCanvas();
		}
	
protected voidrefreshInfoCanvas()

		peerInfoCanvas.layout(true);
		Rectangle bounds = peerInfoCanvas.getClientArea();
		if (bounds.width <= 0 || bounds.height <= 0)
			return;

		if (img != null && !img.isDisposed()) {
			img.dispose();
			img = null;
		}

		if (peer == null || peer.getPeerState() != PEPeer.TRANSFERING) {
			GC gc = new GC(peerInfoCanvas);
			gc.fillRectangle(bounds);
			gc.dispose();

			return;
		}

		BitFlags peerHavePieces = peer.getAvailable();
		if (peerHavePieces == null) {
			GC gc = new GC(peerInfoCanvas);
			gc.fillRectangle(bounds);
			gc.dispose();

			return;
		}

		DiskManagerPiece[] dm_pieces = null;

		PEPeerManager pm = peer.getManager();

		DiskManager dm = pm.getDiskManager();

		dm_pieces = dm.getPieces();

		int iNumCols = bounds.width / BLOCK_SIZE;
		int iNeededHeight = (((dm.getNbPieces() - 1) / iNumCols) + 1)
				* BLOCK_SIZE;
		if (sc.getMinHeight() != iNeededHeight) {
			sc.setMinHeight(iNeededHeight);
			sc.layout(true, true);
			bounds = peerInfoCanvas.getClientArea();
		}
		
		img = new Image(peerInfoCanvas.getDisplay(), bounds.width, iNeededHeight);
		GC gcImg = new GC(img);

		try {
			gcImg.setBackground(peerInfoCanvas.getBackground());
			gcImg.fillRectangle(0, 0, bounds.width, iNeededHeight);

			int[] availability = pm.getAvailability();

			int iNextDLPieceID = -1;
			int iDLPieceID = -1;
			int[] ourRequestedPieces = peer.getOutgoingRequestedPieceNumbers();
			if (ourRequestedPieces != null) {
				if (!peer.isChokingMe()) {
					// !choking == downloading

					if (ourRequestedPieces.length > 0) {
						iDLPieceID = ourRequestedPieces[0];
						if (ourRequestedPieces.length > 1)
							iNextDLPieceID = ourRequestedPieces[1];
					}
				} else {
					if (ourRequestedPieces.length > 0)
						iNextDLPieceID = ourRequestedPieces[0];
				}

				//			if (iNextDLPieceID == -1) {
				//				iNextDLPieceID = peer.getNextPieceNumberGuess();
				//			}
			}

			int[] peerRequestedPieces = peer.getIncomingRequestedPieceNumbers();
			if (peerRequestedPieces == null)
				peerRequestedPieces = new int[0];

			int peerNextRequestedPiece = -1;
			if (peerRequestedPieces.length > 0)
				peerNextRequestedPiece = peerRequestedPieces[0];
			Arrays.sort(peerRequestedPieces);

			int iRow = 0;
			int iCol = 0;
			for (int i = 0; i < peerHavePieces.flags.length; i++) {
				int colorIndex;
				boolean done = (dm_pieces == null) ? false : dm_pieces[i].isDone();
				int iXPos = iCol * BLOCK_SIZE;
				int iYPos = iRow * BLOCK_SIZE;

				if (done) {
					if (peerHavePieces.flags[i])
						colorIndex = BLOCKCOLOR_AVAIL_HAVE;
					else
						colorIndex = BLOCKCOLOR_NOAVAIL_HAVE;

					gcImg.setBackground(blockColors[colorIndex]);
					gcImg.fillRectangle(iXPos, iYPos, BLOCK_FILLSIZE, BLOCK_FILLSIZE);
				} else {
					// !done
					boolean partiallyDone = (dm_pieces == null) ? false : dm_pieces[i]
							.getNbWritten() > 0;

					int x = iXPos;
					int width = BLOCK_FILLSIZE;
					if (partiallyDone) {
						if (peerHavePieces.flags[i])
							colorIndex = BLOCKCOLOR_AVAIL_HAVE;
						else
							colorIndex = BLOCKCOLOR_NOAVAIL_HAVE;

						gcImg.setBackground(blockColors[colorIndex]);

						int iNewWidth = (int) (((float) dm_pieces[i].getNbWritten() / dm_pieces[i]
								.getNbBlocks()) * width);
						if (iNewWidth >= width)
							iNewWidth = width - 1;
						else if (iNewWidth <= 0)
							iNewWidth = 1;

						gcImg.fillRectangle(x, iYPos, iNewWidth, BLOCK_FILLSIZE);
						width -= iNewWidth;
						x += iNewWidth;
					}

					if (peerHavePieces.flags[i])
						colorIndex = BLOCKCOLOR_AVAIL_NOHAVE;
					else
						colorIndex = BLOCKCOLOR_NOAVAIL_NOHAVE;

					gcImg.setBackground(blockColors[colorIndex]);
					gcImg.fillRectangle(x, iYPos, width, BLOCK_FILLSIZE);
				}

				// Down Arrow inside box for "dowloading" piece
				if (i == iDLPieceID) {
					gcImg.setBackground(blockColors[BLOCKCOLOR_TRANSFER]);
					gcImg.fillPolygon(new int[] { iXPos, iYPos, iXPos + BLOCK_FILLSIZE,
							iYPos, iXPos + (BLOCK_FILLSIZE / 2), iYPos + BLOCK_FILLSIZE });
				}

				// Small Down Arrow inside box for next download piece
				if (i == iNextDLPieceID) {
					gcImg.setBackground(blockColors[BLOCKCOLOR_NEXT]);
					gcImg.fillPolygon(new int[] { iXPos + 2, iYPos + 2,
							iXPos + BLOCK_FILLSIZE - 1, iYPos + 2,
							iXPos + (BLOCK_FILLSIZE / 2), iYPos + BLOCK_FILLSIZE - 1 });
				}

				// Up Arrow in uploading piece 
				if (i == peerNextRequestedPiece) {
					gcImg.setBackground(blockColors[BLOCKCOLOR_TRANSFER]);
					gcImg.fillPolygon(new int[] { iXPos, iYPos + BLOCK_FILLSIZE,
							iXPos + BLOCK_FILLSIZE, iYPos + BLOCK_FILLSIZE,
							iXPos + (BLOCK_FILLSIZE / 2), iYPos });
				} else if (Arrays.binarySearch(peerRequestedPieces, i) >= 0) {
					// Small Up Arrow each upload request
					gcImg.setBackground(blockColors[BLOCKCOLOR_NEXT]);
					gcImg.fillPolygon(new int[] { iXPos + 1, iYPos + BLOCK_FILLSIZE - 2,
							iXPos + BLOCK_FILLSIZE - 2, iYPos + BLOCK_FILLSIZE - 2,
							iXPos + (BLOCK_FILLSIZE / 2), iYPos + 2 });
				}

				if (availability != null) {
					gcImg.setFont(font);

					String sNumber = String.valueOf(availability[i]);
					Point size = gcImg.stringExtent(sNumber);

					if (availability[i] < 100) {
						int x = iXPos + (BLOCK_FILLSIZE / 2) - (size.x / 2);
						int y = iYPos + (BLOCK_FILLSIZE / 2) - (size.y / 2);
						gcImg.setForeground(blockColors[BLOCKCOLOR_AVAILCOUNT]);
						gcImg.drawText(sNumber, x, y, true);
					}
				}

				iCol++;
				if (iCol >= iNumCols) {
					iCol = 0;
					iRow++;
				}
			}
		} catch (Exception e) {
			Logger.log(new LogEvent(LogIDs.GUI, "drawing piece map", e));
		} finally {
			gcImg.dispose();
		}

		peerInfoCanvas.redraw();