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("Main Task", 100);
24 * doSomeWork(pm, 30);
25 * SubProgressMonitor subMonitor = new SubProgressMonitor(pm, 40);
26 * try {
27 * subMonitor.beginTask("", 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 }