/****************************************************************************** * Copyright (c) 2007 g-Eclipse consortium * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Initial development of the original code was made for * project g-Eclipse founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributor(s): * UCY (http://www.cs.ucy.ac.cy) * - Harald Gjermundrod (harald@cs.ucy.ac.cy) * *****************************************************************************/ package eu.geclipse.batch.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Shell; import eu.geclipse.batch.ui.internal.Activator; import eu.geclipse.batch.ui.internal.Messages; /** * Progress bar dialog, which are separated into major tasks. Within each major * task there are minor tasks. The driver progress the minor and major tasks. */ public class ProgressDialog extends Dialog { private volatile boolean isClosed = false; private String processMessage; private String shellTitle; private Image[] processImages; private Label processMessageLabel; private Button closeButton; private Composite cancelComposite; private Label lineLabel; private Composite progressBarComposite; private CLabel message; private ProgressBar progressBar; private Shell shell; private Display display; private int majorTasks; private int minorTasks; private int currentMajorTask; private int currentMinorTasks; private int currentMajorOffset; private double currentMinorOffset; private int progressTiks; private String[] taskDescriptions; /** * Default constructor * @param parent The parent shell */ public ProgressDialog( final Shell parent ) { super( parent ); this.currentMajorTask = 0; this.minorTasks = 0; this.majorTasks = 0; this.taskDescriptions = null; this.display = null; this.progressTiks = 100; this.processMessage = Messages.getString( "ProgressDialog.PleaseWait" ); //$NON-NLS-1$ this.processImages = new Image[] { Activator.getDefault().getImageRegistry().get( Activator.IMG_BUSY_ARROW1 ), Activator.getDefault().getImageRegistry().get( Activator.IMG_BUSY_ARROW2 ), Activator.getDefault().getImageRegistry().get( Activator.IMG_BUSY_ARROW3 ), Activator.getDefault().getImageRegistry().get( Activator.IMG_BUSY_ARROW4 ) }; } /** * @param numMajorTasks How many major task this task bar should represent * @param descriptions Optional description of the major tasks * @param dialogTitle The title of the dialog */ public void initInformation( final int numMajorTasks, final String[] descriptions, final String dialogTitle ) { this.majorTasks = numMajorTasks; this.shellTitle = dialogTitle; this.taskDescriptions = new String[ this.majorTasks ]; // If no description is given we create some if ( null == descriptions ) { for ( int i = 0; i < this.majorTasks; ++i ) this.taskDescriptions[ i ] = Messages.getString( "ProgressDialog.WorkOnTask" ) + i; //$NON-NLS-1$ } else { for ( int i = 0; i < this.majorTasks; ++i ) this.taskDescriptions[ i ] = Messages.getString( "ProgressDialog.WorkOnTask" ) + descriptions[ i ]; //$NON-NLS-1$ } } /** * Move the progress bar to the next major task * @param numMinTasks How many minor tasks are there in the next major task */ public void moveNextMajorTask( final int numMinTasks ) { // The display is closed, so don't update the graphics if ( !this.isClosed ) { // Update the text this.display.syncExec( new Runnable() { @SuppressWarnings("synthetic-access") public void run() { ProgressDialog.this.processMessageLabel.setText( ProgressDialog.this.taskDescriptions[ ProgressDialog.this.currentMajorTask ] ); } }); } this.minorTasks = numMinTasks; this.currentMinorTasks = 0; ++this.currentMajorTask; this.currentMajorOffset = ( this.progressTiks / this.majorTasks ) * ( this.currentMajorTask - 1 ); this.currentMinorOffset = ( double )( this.progressTiks / this.majorTasks ) / this.minorTasks; } /** * Move the progress bar one minor step within the major task */ public void moveNextMinor( ) { ++this.currentMinorTasks; // The display is closed, so don't update the graphics if ( !this.isClosed ) { this.display.syncExec( new Runnable() { @SuppressWarnings("synthetic-access") public void run() { int selection = ProgressDialog.this.currentMajorOffset + ( int ) Math.floor( ( ProgressDialog.this.currentMinorTasks * ProgressDialog.this.currentMinorOffset ) ); ProgressDialog.this.progressBar.setSelection( selection ); // Update the image ProgressDialog.this.message.setImage( ProgressDialog.this.processImages[ ProgressDialog.this.currentMinorTasks % 4 ] ); } } ); } } /** * Opens the progress-bar dialog */ public void open() { createContents(); this.shell.open(); this.shell.layout(); } /** * Closes the progress-bar dialog */ public void close() { this.display.syncExec( new Runnable() { @SuppressWarnings("synthetic-access") public void run() { ProgressDialog.this.isClosed = true; ProgressDialog.this.shell.dispose(); } }); } /** * Draws the dialog and inits its contents */ protected void createContents() { Point dialogSize = new Point( 480, 180 ); final GridLayout gridLayout = new GridLayout(); gridLayout.verticalSpacing = 10; this.shell = new Shell( getParent(), SWT.TITLE | SWT.PRIMARY_MODAL ); this.display = this.shell.getDisplay(); this.shell.setLayout( gridLayout ); this.shell.setSize( dialogSize ); this.shell.setText( this.shellTitle ); // Move the dialog to the center of the parent shell Rectangle shellBounds = getParent().getBounds(); this.shell.setLocation( shellBounds.x + ( shellBounds.width - dialogSize.x) / 2, shellBounds.y + ( shellBounds.height - dialogSize.y) / 2 ); final Composite composite = new Composite( this.shell, SWT.NONE ); composite.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false ) ); composite.setLayout( new GridLayout() ); this.message = new CLabel( composite, SWT.NONE ); this.message.setImage( this.processImages[ 0 ] ); this.message.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false ) ); this.message.setText( this.processMessage ); this.progressBarComposite = new Composite( this.shell, SWT.NONE ); this.progressBarComposite.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, false, false ) ); this.progressBarComposite.setLayout( new FillLayout() ); this.progressBar = new ProgressBar( this.progressBarComposite, SWT.SMOOTH ); this.progressBar.setMaximum( this.progressTiks ); this.processMessageLabel = new Label( this.shell, SWT.NONE ); this.processMessageLabel.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, false, false ) ); this.lineLabel = new Label( this.shell, SWT.HORIZONTAL | SWT.SEPARATOR ); this.lineLabel.setLayoutData( new GridData(GridData.FILL, GridData.CENTER, false, false ) ); this.cancelComposite = new Composite( this.shell, SWT.NONE ); this.cancelComposite.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); final GridLayout gridLayoutCancel = new GridLayout(); gridLayoutCancel.numColumns = 2; this.cancelComposite.setLayout( gridLayoutCancel ); this.closeButton = new Button( this.cancelComposite, SWT.NONE ); this.closeButton.addSelectionListener( new SelectionAdapter() { @SuppressWarnings("synthetic-access") @Override public void widgetSelected( final SelectionEvent e ) { ProgressDialog.this.isClosed = true; ProgressDialog.this.shell.dispose(); } }); this.closeButton.setLayoutData( new GridData( 80, SWT.DEFAULT ) ); this.closeButton.setText( Messages.getString( "ProgressDialog.Close" ) ); //$NON-NLS-1$ this.closeButton.setEnabled( true ); } }