/* * Created on 27 Jul 2006 * Created by Paul Gardner * 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.progress; import java.io.InputStream; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.util.AERunnable; import org.gudy.azureus2.core3.util.AEThread; import org.gudy.azureus2.core3.util.Constants; import org.gudy.azureus2.core3.util.Debug; import org.gudy.azureus2.core3.util.DelayedEvent; import org.gudy.azureus2.ui.swt.ImageRepository; import org.gudy.azureus2.ui.swt.Utils; import org.gudy.azureus2.ui.swt.mainwindow.SWTThread; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreOperation; import com.aelitis.azureus.core.AzureusCoreOperationListener; public class ProgressWindow { public static void register( AzureusCore core ) { core.addOperationListener( new AzureusCoreOperationListener() { public boolean operationCreated( AzureusCoreOperation operation ) { if ( operation.getOperationType() == AzureusCoreOperation.OP_FILE_MOVE && Utils.isThisThreadSWT()){ if ( operation.getTask() != null ){ new ProgressWindow( operation ); return( true ); } } return( false ); } }); } private volatile Shell shell; private volatile boolean task_complete; public ProgressWindow( final AzureusCoreOperation operation ) { final RuntimeException[] error = {null}; new DelayedEvent( "ProgWin", 1000, new AERunnable() { public void runSupport() { synchronized( this ){ if ( !task_complete ){ Utils.execSWTThread( new Runnable() { public void run() { synchronized( this ){ if ( !task_complete ){ showDialog(); } } } }, false ); } } } }); new AEThread( "ProgressWindow", true ) { public void runSupport() { try{ // Thread.sleep(10000); operation.getTask().run( operation ); }catch( RuntimeException e ){ error[0] = e; }catch( Throwable e ){ error[0] = new RuntimeException( e ); }finally{ synchronized( this ){ task_complete = true; Utils.execSWTThread( new Runnable(){public void run(){}}, true ); } } } }.start(); try{ final Display display = SWTThread.getInstance().getDisplay(); while( !( task_complete || display.isDisposed())){ if (!display.readAndDispatch()) display.sleep(); } }finally{ // bit of boiler plate in case something fails in the dispatch loop synchronized( this ){ task_complete = true; } try{ if ( shell != null && !shell.isDisposed()){ shell.dispose(); } }catch( Throwable e ){ Debug.printStackTrace(e); } } if ( error[0] != null ){ throw( error[0] ); } } protected void showDialog() { shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createMainShell( ( SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL )); shell.setText( MessageText.getString( "progress.window.title" )); Utils.setShellIcon(shell); shell.addListener( SWT.Close, new Listener() { public void handleEvent( org.eclipse.swt.widgets.Event event) { event.doit = false; } }); GridLayout layout = new GridLayout(); layout.numColumns = 2; shell.setLayout(layout); InputStream is = ImageRepository.getImageAsStream( "working" ); if ( is == null ){ new Label( shell, SWT.NULL ); }else{ final ImageLoader loader = new ImageLoader(); final Color background = shell.getBackground(); loader.load( is ); final Canvas canvas = new Canvas( shell, SWT.NULL ) { public Point computeSize(int wHint, int hHint,boolean changed ) { return( new Point(loader.logicalScreenWidth,loader.logicalScreenWidth)); } }; final GC canvas_gc = new GC( canvas ); new AEThread("GifAnim", true ) { private Image image; private boolean useGIFBackground; public void runSupport() { Display display = shell.getDisplay(); ImageData[] image_data = loader.data; /* Create an off-screen image to draw on, and fill it with the shell background. */ Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight); GC offScreenImageGC = new GC(offScreenImage); offScreenImageGC.setBackground(background); offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight); try{ /* Create the first image and draw it on the off-screen image. */ int imageDataIndex = 0; ImageData imageData = image_data[imageDataIndex]; if (image != null && !image.isDisposed()) image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Now loop through the images, creating and drawing each one * on the off-screen image before drawing it on the shell. */ int repeatCount = loader.repeatCount; while ( !task_complete && loader.repeatCount == 0 || repeatCount > 0) { switch (imageData.disposalMethod){ case SWT.DM_FILL_BACKGROUND: /* Fill with the background color before drawing. */ Color bgColor = null; if (useGIFBackground && loader.backgroundPixel != -1) { bgColor = new Color(display, imageData.palette.getRGB(loader.backgroundPixel)); } offScreenImageGC.setBackground(bgColor != null ? bgColor : background); offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height); if (bgColor != null) bgColor.dispose(); break; case SWT.DM_FILL_PREVIOUS: /* Restore the previous image before drawing. */ offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); break; } imageDataIndex = (imageDataIndex + 1) % image_data.length; imageData = image_data[imageDataIndex]; image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Draw the off-screen image to the shell. */ canvas_gc.drawImage(offScreenImage, 0, 0); /* Sleep for the specified delay time (adding commonly-used slow-down fudge factors). */ try { int ms = imageData.delayTime * 10; if (ms < 20) ms += 30; if (ms < 30) ms += 10; Thread.sleep(ms); } catch (InterruptedException e) { } /* If we have just drawn the last image, decrement the repeat count and start again. */ if (imageDataIndex == image_data.length - 1) repeatCount--; } } catch (SWTException ex) { ex.printStackTrace(); } finally { if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage.dispose(); if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC.dispose(); if (image != null && !image.isDisposed()) image.dispose(); } } }.start(); } Label label = new Label(shell, SWT.NONE); label.setText(MessageText.getString( "progress.window.msg.filemove" )); GridData gridData = new GridData(); label.setLayoutData(gridData); shell.pack(); Utils.centreWindow( shell ); shell.open(); } }