View Javadoc

1   /*
2    * $Id: SubProgressMonitor.java,v 1.18 2011/06/16 09:29:42 jbmeslin Exp $
3    * 
4    */
5   /*******************************************************************************
6    * Copyright (c) 2000, 2004 IBM Corporation and others.
7    * All rights reserved. This program and the accompanying materials
8    * are made available under the terms of the Eclipse Public License v1.0
9    * which accompanies this distribution, and is available at
10   * http://www.eclipse.org/legal/epl-v10.html
11   * 
12   * Contributors:
13   *     IBM Corporation - initial API and implementation
14   *******************************************************************************/
15  package org.rcfaces.core.progressMonitor;
16  
17  /**
18   * A progress monitor that uses a given amount of work ticks from a parent
19   * monitor. It can be used as follows:
20   * 
21   * <pre>
22   * try {
23   *     pm.beginTask(&quot;Main Task&quot;, 100);
24   *     doSomeWork(pm, 30);
25   *     SubProgressMonitor subMonitor = new SubProgressMonitor(pm, 40);
26   *     try {
27   *         subMonitor.beginTask(&quot;&quot;, 300);
28   *         doSomeWork(subMonitor, 300);
29   *     } finally {
30   *         subMonitor.done();
31   *     }
32   *     doSomeWork(pm, 30);
33   * } finally {
34   *     pm.done();
35   * }
36   * </pre>
37   * 
38   * <p>
39   * This class may be instantiated or subclassed by clients.
40   * </p>
41   */
42  public class SubProgressMonitor extends ProgressMonitorWrapper {
43  
44      /**
45       * Style constant indicating that calls to <code>subTask</code> should not
46       * have any effect.
47       * 
48       * @see #SubProgressMonitor(IProgressMonitor,int,int)
49       */
50      public static final int SUPPRESS_SUBTASK_LABEL = 1 << 1;
51  
52      /**
53       * Style constant indicating that the main task label should be prepended to
54       * the subtask label.
55       * 
56       * @see #SubProgressMonitor(IProgressMonitor,int,int)
57       */
58      public static final int PREPEND_MAIN_LABEL_TO_SUBTASK = 1 << 2;
59  
60      private int parentTicks = 0;
61  
62      private double sentToParent = 0.0;
63  
64      private double scale = 0.0;
65  
66      private int nestedBeginTasks = 0;
67  
68      private boolean usedUp = false;
69  
70      private int style;
71  
72      private String mainTaskLabel;
73  
74      /**
75       * Creates a new sub-progress monitor for the given monitor. The sub
76       * progress monitor uses the given number of work ticks from its parent
77       * monitor.
78       * 
79       * @param monitor
80       *            the parent progress monitor
81       * @param ticks
82       *            the number of work ticks allocated from the parent monitor
83       */
84      public SubProgressMonitor(IProgressMonitor monitor, int ticks) {
85          this(monitor, ticks, 0);
86      }
87  
88      /**
89       * Creates a new sub-progress monitor for the given monitor. The sub
90       * progress monitor uses the given number of work ticks from its parent
91       * monitor.
92       * 
93       * @param monitor
94       *            the parent progress monitor
95       * @param ticks
96       *            the number of work ticks allocated from the parent monitor
97       * @param style
98       *            one of
99       *            <ul>
100      *            <li> <code>SUPPRESS_SUBTASK_LABEL</code> </li>
101      *            <li> <code>PREPEND_MAIN_LABEL_TO_SUBTASK</code> </li>
102      *            </ul>
103      * @see #SUPPRESS_SUBTASK_LABEL
104      * @see #PREPEND_MAIN_LABEL_TO_SUBTASK
105      */
106     public SubProgressMonitor(IProgressMonitor monitor, int ticks, int style) {
107         super(monitor);
108         this.parentTicks = ticks;
109         this.style = style;
110     }
111 
112     /*
113      * (Intentionally not javadoc'd) Implements the method <code>IProgressMonitor.beginTask</code>.
114      * 
115      * Starts a new main task. Since this progress monitor is a sub progress
116      * monitor, the given name will NOT be used to update the progress bar's
117      * main task label. That means the given string will be ignored. If style
118      * <code>PREPEND_MAIN_LABEL_TO_SUBTASK <code> is specified, then the given
119      * string will be prepended to every string passed to <code>subTask(String)</code>.
120      */
121     public void beginTask(String name, int totalWork) {
122         nestedBeginTasks++;
123         // Ignore nested begin task calls.
124         if (nestedBeginTasks > 1) {
125             return;
126         }
127         // be safe: if the argument would cause math errors (zero or
128         // negative), just use 0 as the scale. This disables progress for
129         // this submonitor.
130         scale = totalWork <= 0 ? 0 : (double) parentTicks / (double) totalWork;
131         if ((style & PREPEND_MAIN_LABEL_TO_SUBTASK) != 0) {
132             mainTaskLabel = name;
133         }
134     }
135 
136     /*
137      * (Intentionally not javadoc'd) Implements the method <code>IProgressMonitor.done</code>.
138      */
139     public void done() {
140         // Ignore if more done calls than beginTask calls or if we are still
141         // in some nested beginTasks
142         if (nestedBeginTasks == 0 || --nestedBeginTasks > 0)
143             return;
144         // Send any remaining ticks and clear out the subtask text
145         double remaining = parentTicks - sentToParent;
146         if (remaining > 0)
147             super.internalWorked(remaining);
148         subTask(""); //$NON-NLS-1$
149         sentToParent = 0;
150     }
151 
152     /*
153      * (Intentionally not javadoc'd) Implements the internal method <code>IProgressMonitor.internalWorked</code>.
154      */
155     public void internalWorked(double work) {
156         if (usedUp || nestedBeginTasks != 1) {
157             return;
158         }
159 
160         double realWork = scale * work;
161         // System.out.println("Sub monitor: " + realWork);
162         super.internalWorked(realWork);
163         sentToParent += realWork;
164         if (sentToParent >= parentTicks) {
165             usedUp = true;
166         }
167     }
168 
169     /*
170      * (Intentionally not javadoc'd) Implements the method <code>IProgressMonitor.subTask</code>.
171      */
172     public void subTask(String name) {
173         if ((style & SUPPRESS_SUBTASK_LABEL) != 0) {
174             return;
175         }
176 
177         String label = name;
178         if ((style & PREPEND_MAIN_LABEL_TO_SUBTASK) != 0
179                 && mainTaskLabel != null && mainTaskLabel.length() > 0) {
180             label = mainTaskLabel + ' ' + label;
181         }
182         super.subTask(label);
183     }
184 
185     /*
186      * (Intentionally not javadoc'd) Implements the method <code>IProgressMonitor.worked</code>.
187      */
188     public void worked(int work) {
189         internalWorked(work);
190     }
191 }