2 * Copyright (C) 2011 The Android Open Source Project
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package com.android.sdkuilib.internal.tasks;
\r
19 import com.android.sdklib.internal.repository.ITaskMonitor;
\r
21 import org.eclipse.swt.widgets.ProgressBar;
\r
24 * Internal class that implements the logic of an {@link ITaskMonitor}.
\r
25 * It doesn't deal with any UI directly. Instead it delegates the UI to
\r
26 * the provided {@link IProgressUiProvider}.
\r
28 class TaskMonitorImpl implements ITaskMonitor {
\r
30 private static final double MAX_COUNT = 10000.0;
\r
32 private interface ISubTaskMonitor extends ITaskMonitor {
\r
33 public void subIncProgress(double realDelta);
\r
36 private double mIncCoef = 0;
\r
37 private double mValue = 0;
\r
38 private final IProgressUiProvider mUi;
\r
41 * Returns true if the given {@code monitor} is an instance of {@link TaskMonitorImpl}
\r
42 * or its private SubTaskMonitor.
\r
44 public static boolean isTaskMonitorImpl(ITaskMonitor monitor) {
\r
45 return monitor instanceof TaskMonitorImpl || monitor instanceof SubTaskMonitor;
\r
49 * Constructs a new {@link TaskMonitorImpl} that relies on the given
\r
50 * {@link IProgressUiProvider} to change the user interface.
\r
51 * @param ui The {@link IProgressUiProvider}. Cannot be null.
\r
53 public TaskMonitorImpl(IProgressUiProvider ui) {
\r
57 /** Returns the {@link IProgressUiProvider} passed to the constructor. */
\r
58 public IProgressUiProvider getUiProvider() {
\r
63 * Sets the description in the current task dialog.
\r
64 * This method can be invoked from a non-UI thread.
\r
66 public void setDescription(String format, Object... args) {
\r
67 final String text = String.format(format, args);
\r
68 mUi.setDescription(text);
\r
72 * Logs a "normal" information line.
\r
73 * This method can be invoked from a non-UI thread.
\r
75 public void log(String format, Object... args) {
\r
76 String text = String.format(format, args);
\r
81 * Logs an "error" information line.
\r
82 * This method can be invoked from a non-UI thread.
\r
84 public void logError(String format, Object... args) {
\r
85 String text = String.format(format, args);
\r
90 * Logs a "verbose" information line, that is extra details which are typically
\r
91 * not that useful for the end-user and might be hidden until explicitly shown.
\r
92 * This method can be invoked from a non-UI thread.
\r
94 public void logVerbose(String format, Object... args) {
\r
95 String text = String.format(format, args);
\r
96 mUi.logVerbose(text);
\r
100 * Sets the max value of the progress bar.
\r
101 * This method can be invoked from a non-UI thread.
\r
103 * Weird things will happen if setProgressMax is called multiple times
\r
104 * *after* {@link #incProgress(int)}: we don't try to adjust it on the
\r
107 * @see ProgressBar#setMaximum(int)
\r
109 public void setProgressMax(int max) {
\r
111 // Always set the dialog's progress max to 10k since it only handles
\r
112 // integers and we want to have a better inner granularity. Instead
\r
113 // we use the max to compute a coefficient for inc deltas.
\r
114 mUi.setProgressMax((int) MAX_COUNT);
\r
115 mIncCoef = max > 0 ? MAX_COUNT / max : 0;
\r
116 assert mIncCoef > 0;
\r
119 public int getProgressMax() {
\r
120 return mIncCoef > 0 ? (int) (MAX_COUNT / mIncCoef) : 0;
\r
124 * Increments the current value of the progress bar.
\r
126 * This method can be invoked from a non-UI thread.
\r
128 public void incProgress(int delta) {
\r
129 if (delta > 0 && mIncCoef > 0) {
\r
130 internalIncProgress(delta * mIncCoef);
\r
134 private void internalIncProgress(double realDelta) {
\r
135 mValue += realDelta;
\r
136 mUi.setProgress((int)mValue);
\r
140 * Returns the current value of the progress bar,
\r
141 * between 0 and up to {@link #setProgressMax(int)} - 1.
\r
143 * This method can be invoked from a non-UI thread.
\r
145 public int getProgress() {
\r
146 // mIncCoef is 0 if setProgressMax hasn't been used yet.
\r
147 return mIncCoef > 0 ? (int)(mUi.getProgress() / mIncCoef) : 0;
\r
151 * Returns true if the "Cancel" button was selected.
\r
152 * It is up to the task thread to pool this and exit.
\r
154 public boolean isCancelRequested() {
\r
155 return mUi.isCancelRequested();
\r
159 * Display a yes/no question dialog box.
\r
161 * This implementation allow this to be called from any thread, it
\r
162 * makes sure the dialog is opened synchronously in the ui thread.
\r
164 * @param title The title of the dialog box
\r
165 * @param message The error message
\r
166 * @return true if YES was clicked.
\r
168 public boolean displayPrompt(final String title, final String message) {
\r
169 return mUi.displayPrompt(title, message);
\r
173 * Creates a sub-monitor that will use up to tickCount on the progress bar.
\r
174 * tickCount must be 1 or more.
\r
176 public ITaskMonitor createSubMonitor(int tickCount) {
\r
177 assert mIncCoef > 0;
\r
178 assert tickCount > 0;
\r
179 return new SubTaskMonitor(this, null, mValue, tickCount * mIncCoef);
\r
182 // ----- ISdkLog interface ----
\r
184 public void error(Throwable throwable, String errorFormat, Object... arg) {
\r
185 if (errorFormat != null) {
\r
186 logError("Error: " + errorFormat, arg);
\r
189 if (throwable != null) {
\r
190 logError("%s", throwable.getMessage()); //$NON-NLS-1$
\r
194 public void warning(String warningFormat, Object... arg) {
\r
195 log("Warning: " + warningFormat, arg);
\r
198 public void printf(String msgFormat, Object... arg) {
\r
199 log(msgFormat, arg);
\r
202 // ----- Sub Monitor -----
\r
204 private static class SubTaskMonitor implements ISubTaskMonitor {
\r
206 private final TaskMonitorImpl mRoot;
\r
207 private final ISubTaskMonitor mParent;
\r
208 private final double mStart;
\r
209 private final double mSpan;
\r
210 private double mSubValue;
\r
211 private double mSubCoef;
\r
214 * Creates a new sub task monitor which will work for the given range [start, start+span]
\r
217 * @param taskMonitor The ProgressTask root
\r
218 * @param parent The immediate parent. Can be the null or another sub task monitor.
\r
219 * @param start The start value in the root's coordinates
\r
220 * @param span The span value in the root's coordinates
\r
222 public SubTaskMonitor(TaskMonitorImpl taskMonitor,
\r
223 ISubTaskMonitor parent,
\r
226 mRoot = taskMonitor;
\r
233 public boolean isCancelRequested() {
\r
234 return mRoot.isCancelRequested();
\r
237 public void setDescription(String format, Object... args) {
\r
238 mRoot.setDescription(format, args);
\r
241 public void log(String format, Object... args) {
\r
242 mRoot.log(format, args);
\r
245 public void logError(String format, Object... args) {
\r
246 mRoot.logError(format, args);
\r
249 public void logVerbose(String format, Object... args) {
\r
250 mRoot.logVerbose(format, args);
\r
253 public void setProgressMax(int max) {
\r
255 mSubCoef = max > 0 ? mSpan / max : 0;
\r
256 assert mSubCoef > 0;
\r
259 public int getProgressMax() {
\r
260 return mSubCoef > 0 ? (int) (mSpan / mSubCoef) : 0;
\r
263 public int getProgress() {
\r
264 assert mSubCoef > 0;
\r
265 return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0;
\r
268 public void incProgress(int delta) {
\r
269 if (delta > 0 && mSubCoef > 0) {
\r
270 subIncProgress(delta * mSubCoef);
\r
274 public void subIncProgress(double realDelta) {
\r
275 mSubValue += realDelta;
\r
276 if (mParent != null) {
\r
277 mParent.subIncProgress(realDelta);
\r
279 mRoot.internalIncProgress(realDelta);
\r
283 public boolean displayPrompt(String title, String message) {
\r
284 return mRoot.displayPrompt(title, message);
\r
287 public ITaskMonitor createSubMonitor(int tickCount) {
\r
288 assert mSubCoef > 0;
\r
289 assert tickCount > 0;
\r
290 return new SubTaskMonitor(mRoot,
\r
293 tickCount * mSubCoef);
\r
296 // ----- ISdkLog interface ----
\r
298 public void error(Throwable throwable, String errorFormat, Object... arg) {
\r
299 mRoot.error(throwable, errorFormat, arg);
\r
302 public void warning(String warningFormat, Object... arg) {
\r
303 mRoot.warning(warningFormat, arg);
\r
306 public void printf(String msgFormat, Object... arg) {
\r
307 mRoot.printf(msgFormat, arg);
\r