Package org.eclipse.ui.internal.progress

Source Code of org.eclipse.ui.internal.progress.BlockedJobsDialog$BlockedUIElement

/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others.
* 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
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.progress;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IconAndMessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.progress.WorkbenchJob;

/**
* The BlockedJobsDialog class displays a dialog that provides information on
* the running jobs.
*/
public class BlockedJobsDialog extends IconAndMessageDialog {
  /**
   * The singleton dialog instance. A singleton avoids the possibility of
   * recursive dialogs being created. The singleton is created when a dialog
   * is requested, and cleared when the dialog is disposed.
   */
  protected static BlockedJobsDialog singleton;

  /**
   * The running jobs progress viewer.
   */
  private DetailedProgressViewer viewer;

  /**
   * The name of the task that is being blocked.
   */
  private String blockedTaskName = null;

  /**
   * The Cancel button control.
   */
  private Button cancelSelected;

  /**
   * The cursor for the buttons.
   */
  private Cursor arrowCursor;

  /**
   * The cursor for the Shell.
   */
  private Cursor waitCursor;

  private IProgressMonitor blockingMonitor;

  private JobTreeElement blockedElement = new BlockedUIElement();

  /**
   * The BlockedUIElement is the JobTreeElement that represents the blocked
   * job in the dialog.
   */
  private class BlockedUIElement extends JobTreeElement {

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#getChildren()
     */
    Object[] getChildren() {
      return ProgressManagerUtil.EMPTY_OBJECT_ARRAY;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#getDisplayString()
     */
    String getDisplayString() {
      if (blockedTaskName == null || blockedTaskName.length() == 0) {
        return ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement;
      }
      return blockedTaskName;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#getDisplayImage()
     */
    public Image getDisplayImage() {
      return JFaceResources.getImage(ProgressManager.WAITING_JOB_KEY);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#getParent()
     */
    Object getParent() {
      return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#hasChildren()
     */
    boolean hasChildren() {
      return false;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#isActive()
     */
    boolean isActive() {
      return true;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#isJobInfo()
     */
    boolean isJobInfo() {
      return false;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#cancel()
     */
    public void cancel() {
      blockingMonitor.setCanceled(true);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.internal.progress.JobTreeElement#isCancellable()
     */
    public boolean isCancellable() {
      return true;
    }
  }

  /**
   * Creates a progress monitor dialog under the given shell. It also sets the
   * dialog's message. The dialog is opened automatically after a reasonable
   * delay. When no longer needed, the dialog must be closed by calling
   * <code>close(IProgressMonitor)</code>, where the supplied monitor is
   * the same monitor passed to this factory method.
   *
   * @param parentShell
   *            The parent shell, or <code>null</code> to create a top-level
   *            shell. If the parentShell is not null we will open immediately
   *            as parenting has been determined. If it is <code>null</code>
   *            then the dialog will not open until there is no modal shell
   *            blocking it.
   * @param blockedMonitor
   *            The monitor that is currently blocked
   * @param reason
   *            A status describing why the monitor is blocked
   * @param taskName
   *            A name to give the blocking task in the dialog
   * @return BlockedJobsDialog
   */
  public static BlockedJobsDialog createBlockedDialog(Shell parentShell,
      IProgressMonitor blockedMonitor, IStatus reason, String taskName) {
    // use an existing dialog if available
    if (singleton != null) {
      return singleton;
    }
    singleton = new BlockedJobsDialog(parentShell, blockedMonitor, reason);

    if (taskName == null || taskName.length() == 0)
      singleton
          .setBlockedTaskName(ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement);
    else
      singleton.setBlockedTaskName(taskName);

    /**
     * If there is no parent shell we have not been asked for a parent so we
     * want to avoid blocking. If there is a parent then it is OK to open.
     */
    if (parentShell == null) {
      // create the job that will open the dialog after a delay.
      WorkbenchJob dialogJob = new WorkbenchJob(
          WorkbenchMessages.EventLoopProgressMonitor_OpenDialogJobName) {
        /*
         * (non-Javadoc)
         *
         * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
         */
        public IStatus runInUIThread(IProgressMonitor monitor) {
          if (singleton == null) {
            return Status.CANCEL_STATUS;
          }
          if (ProgressManagerUtil.rescheduleIfModalShellOpen(this)) {
            return Status.CANCEL_STATUS;
          }
          singleton.open();
          return Status.OK_STATUS;
        }
      };
      // Wait for long operation time to prevent a proliferation
      // of dialogs
      dialogJob.setSystem(true);
      dialogJob.schedule(PlatformUI.getWorkbench().getProgressService()
          .getLongOperationTime());
    } else {
      singleton.open();
    }

    return singleton;
  }

  /**
   * monitor is done. Clear the receiver.
   *
   * @param monitor
   *            The monitor that is now cleared.
   */
  public static void clear(IProgressMonitor monitor) {
    if (singleton == null) {
      return;
    }
    singleton.close(monitor);

  }

  /**
   * Creates a progress monitor dialog under the given shell. It also sets the
   * dialog's\ message. <code>open</code> is non-blocking.
   *
   * @param parentShell
   *            The parent shell, or <code>null</code> to create a top-level
   *            shell.
   * @param blocking
   *            The monitor that is blocking the job
   * @param blockingStatus
   *            A status describing why the monitor is blocked
   */
  private BlockedJobsDialog(Shell parentShell, IProgressMonitor blocking,
      IStatus blockingStatus) {
    super(parentShell == null ? ProgressManagerUtil.getDefaultParent()
        : parentShell);
    blockingMonitor = blocking;
    setShellStyle(SWT.BORDER | SWT.TITLE | SWT.APPLICATION_MODAL
        | SWT.RESIZE | getDefaultOrientation());
    // no close button
    setBlockOnOpen(false);
    setMessage(blockingStatus.getMessage());
  }

  /**
   * This method creates the dialog area under the parent composite.
   *
   * @param parent
   *            The parent Composite.
   *
   * @return parent The parent Composite.
   */
  protected Control createDialogArea(Composite parent) {
    setMessage(message);
    createMessageArea(parent);
    showJobDetails(parent);
    return parent;
  }

  /**
   * This method creates a dialog area in the parent composite and displays a
   * progress tree viewer of the running jobs.
   *
   * @param parent
   *            The parent Composite.
   */
  void showJobDetails(Composite parent) {
    viewer = new DetailedProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL
        | SWT.V_SCROLL | SWT.BORDER);
    viewer.setComparator(new ViewerComparator() {
      /*
       * (non-Javadoc)
       *
       * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
       *      java.lang.Object, java.lang.Object)
       */
      public int compare(Viewer testViewer, Object e1, Object e2) {
        return ((Comparable) e1).compareTo(e2);
      }
    });
    ProgressViewerContentProvider provider = getContentProvider();
    viewer.setContentProvider(provider);
    viewer.setInput(provider);
    viewer.setLabelProvider(new ProgressLabelProvider());
    GridData data = new GridData(GridData.GRAB_HORIZONTAL
        | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
    data.horizontalSpan = 2;
    int heightHint = convertHeightInCharsToPixels(10);
    data.heightHint = heightHint;
    viewer.getControl().setLayoutData(data);
  }

  /**
   * Return the content provider used for the receiver.
   *
   * @return ProgressTreeContentProvider
   */
  private ProgressViewerContentProvider getContentProvider() {
    return new ProgressViewerContentProvider(viewer, true, false) {

      /*
       * (non-Javadoc)
       *
       * @see org.eclipse.ui.internal.progress.ProgressViewerContentProvider#getElements(java.lang.Object)
       */
      public Object[] getElements(Object inputElement) {
        Object[] elements = super.getElements(inputElement);
        Object[] result = new Object[elements.length + 1];
        System.arraycopy(elements, 0, result, 1, elements.length);
        result[0] = blockedElement;
        return result;
      }
    };
  }

  /**
   * Clear the cursors in the dialog.
   */
  private void clearCursors() {
    clearCursor(cancelSelected);
    clearCursor(getShell());
    if (arrowCursor != null) {
      arrowCursor.dispose();
    }
    if (waitCursor != null) {
      waitCursor.dispose();
    }
    arrowCursor = null;
    waitCursor = null;
  }

  /**
   * Clear the cursor on the supplied control.
   *
   * @param control
   */
  private void clearCursor(Control control) {
    if (control != null && !control.isDisposed()) {
      control.setCursor(null);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
   */
  protected void configureShell(Shell shell) {
    super.configureShell(shell);
    shell.setText(ProgressMessages.BlockedJobsDialog_BlockedTitle);
    if (waitCursor == null) {
      waitCursor = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
    }
    shell.setCursor(waitCursor);
  }

  /**
   * This method sets the message in the message label.
   *
   * @param messageString -
   *            the String for the message area
   */
  private void setMessage(String messageString) {
    // must not set null text in a label
    message = messageString == null ? "" : messageString; //$NON-NLS-1$
    if (messageLabel == null || messageLabel.isDisposed()) {
      return;
    }
    messageLabel.setText(message);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.dialogs.IconAndMessageDialog#getImage()
   */
  protected Image getImage() {
    return getInfoImage();
  }

  /**
   * Returns the progress monitor being used for this dialog. This allows
   * recursive blockages to also respond to cancelation.
   *
   * @return IProgressMonitor
   */
  public IProgressMonitor getProgressMonitor() {
    return blockingMonitor;
  }

  /**
   * Requests that the blocked jobs dialog be closed. The supplied monitor
   * must be the same one that was passed to the createBlockedDialog method.
   *
   * @param monitor
   * @return IProgressMonitor
   */
  public boolean close(IProgressMonitor monitor) {
    // ignore requests to close the dialog from all but the first monitor
    if (blockingMonitor != monitor) {
      return false;
    }
    return close();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.dialogs.Dialog#close()
   */
  public boolean close() {
    // Clear the singleton first
    singleton = null;
    clearCursors();
    return super.close();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.dialogs.IconAndMessageDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
   */
  protected Control createButtonBar(Composite parent) {
    // Do nothing here as we want no buttons
    return parent;
  }

  /**
   * @param taskName
   *            The blockedTaskName to set.
   */
  void setBlockedTaskName(String taskName) {
    this.blockedTaskName = taskName;
  }

}
TOP

Related Classes of org.eclipse.ui.internal.progress.BlockedJobsDialog$BlockedUIElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.