SDK Updater: Fetch source XML, display them in tree.
There's a notion of an asynchronous task with a progress bar & status UI. That's still just experimental. Will need some refactoring, etc.
This commit is contained in:
@@ -53,7 +53,7 @@ class Main {
|
|||||||
|
|
||||||
|
|
||||||
/** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
|
/** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
|
||||||
private String mSdkFolder;
|
private String mOsSdkFolder;
|
||||||
/** Logger object. Use this to print normal output, warnings or errors. */
|
/** Logger object. Use this to print normal output, warnings or errors. */
|
||||||
private ISdkLog mSdkLog;
|
private ISdkLog mSdkLog;
|
||||||
/** The SDK manager parses the SDK folder and gives access to the content. */
|
/** The SDK manager parses the SDK folder and gives access to the content. */
|
||||||
@@ -131,18 +131,18 @@ class Main {
|
|||||||
File tools;
|
File tools;
|
||||||
if (toolsDirProp.length() > 0) {
|
if (toolsDirProp.length() > 0) {
|
||||||
tools = new File(toolsDirProp);
|
tools = new File(toolsDirProp);
|
||||||
mSdkFolder = tools.getParent();
|
mOsSdkFolder = tools.getParent();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
tools = new File(".").getCanonicalFile();
|
tools = new File(".").getCanonicalFile();
|
||||||
mSdkFolder = tools.getParent();
|
mOsSdkFolder = tools.getParent();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Will print an error below since mSdkFolder is not defined
|
// Will print an error below since mSdkFolder is not defined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSdkFolder == null) {
|
if (mOsSdkFolder == null) {
|
||||||
errorAndExit("The tools directory property is not set, please make sure you are executing %1$s",
|
errorAndExit("The tools directory property is not set, please make sure you are executing %1$s",
|
||||||
SdkConstants.androidCmdName());
|
SdkConstants.androidCmdName());
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ class Main {
|
|||||||
* Does the basic SDK parsing required for all actions
|
* Does the basic SDK parsing required for all actions
|
||||||
*/
|
*/
|
||||||
private void parseSdk() {
|
private void parseSdk() {
|
||||||
mSdkManager = SdkManager.createManager(mSdkFolder, mSdkLog);
|
mSdkManager = SdkManager.createManager(mOsSdkFolder, mSdkLog);
|
||||||
|
|
||||||
if (mSdkManager == null) {
|
if (mSdkManager == null) {
|
||||||
errorAndExit("Unable to parse SDK content.");
|
errorAndExit("Unable to parse SDK content.");
|
||||||
@@ -234,7 +234,9 @@ class Main {
|
|||||||
*/
|
*/
|
||||||
private void showMainWindow() {
|
private void showMainWindow() {
|
||||||
try {
|
try {
|
||||||
UpdaterWindow window = new UpdaterWindow();
|
UpdaterWindow window = new UpdaterWindow(
|
||||||
|
mOsSdkFolder,
|
||||||
|
false /*userCanChangeSdkRoot*/);
|
||||||
window.open();
|
window.open();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -254,7 +256,7 @@ class Main {
|
|||||||
}
|
}
|
||||||
IAndroidTarget target = targets[targetId - 1];
|
IAndroidTarget target = targets[targetId - 1];
|
||||||
|
|
||||||
ProjectCreator creator = new ProjectCreator(mSdkFolder,
|
ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
|
||||||
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
||||||
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
||||||
OutputLevel.NORMAL,
|
OutputLevel.NORMAL,
|
||||||
@@ -316,7 +318,7 @@ class Main {
|
|||||||
target = targets[targetId - 1];
|
target = targets[targetId - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectCreator creator = new ProjectCreator(mSdkFolder,
|
ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
|
||||||
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
||||||
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
||||||
OutputLevel.NORMAL,
|
OutputLevel.NORMAL,
|
||||||
@@ -766,7 +768,7 @@ class Main {
|
|||||||
mSdkLog.printf("\n"); // empty line
|
mSdkLog.printf("\n"); // empty line
|
||||||
|
|
||||||
// get the list of possible hardware properties
|
// get the list of possible hardware properties
|
||||||
File hardwareDefs = new File (mSdkFolder + File.separator +
|
File hardwareDefs = new File (mOsSdkFolder + File.separator +
|
||||||
SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
|
SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
|
||||||
List<HardwareProperty> list = HardwareProperties.parseHardwareDefinitions(hardwareDefs,
|
List<HardwareProperty> list = HardwareProperties.parseHardwareDefinitions(hardwareDefs,
|
||||||
null /*sdkLog*/);
|
null /*sdkLog*/);
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.sdklib.repository;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants for the sdk-repository XML Schema
|
||||||
|
*/
|
||||||
|
public class SdkRepository {
|
||||||
|
|
||||||
|
public static final String NS_SDK_REPOSITORY =
|
||||||
|
"http://schemas.android.com/sdk/android/repository/1"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public static final String NODE_VERSION = "version"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_REVISION = "revision"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_API_LEVEL = "api-level"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_VENDOR = "vendor"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_NAME = "name"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_TOOL = "tool"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_DOC = "doc"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_ADD_ON = "add-on"; //$NON-NLS-1$
|
||||||
|
public static final String NODE_SDK_REPOSITORY = "sdk-repository"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public static InputStream getXsdStream() {
|
||||||
|
return SdkRepository.class.getResourceAsStream("sdk-repository.xsd"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.php
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.sdklib.repository;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants for the sdk-repository XML Schema
|
|
||||||
*/
|
|
||||||
public class SdkRepositoryConstants {
|
|
||||||
|
|
||||||
public static final String NS_SDK_REPOSITORY =
|
|
||||||
"http://schemas.android.com/sdk/android/repository/1";
|
|
||||||
|
|
||||||
public static InputStream getXsdStream() {
|
|
||||||
return SdkRepositoryConstants.class.getResourceAsStream("sdk-repository.xsd");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -110,7 +110,7 @@ public class TestSdkRepository extends TestCase {
|
|||||||
|
|
||||||
/** Helper method that returns a validator for our XSD */
|
/** Helper method that returns a validator for our XSD */
|
||||||
private Validator getValidator(CaptureErrorHandler handler) throws SAXException {
|
private Validator getValidator(CaptureErrorHandler handler) throws SAXException {
|
||||||
InputStream xsdStream = SdkRepositoryConstants.getXsdStream();
|
InputStream xsdStream = SdkRepository.getXsdStream();
|
||||||
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
Schema schema = factory.newSchema(new StreamSource(xsdStream));
|
Schema schema = factory.newSchema(new StreamSource(xsdStream));
|
||||||
Validator validator = schema.newValidator();
|
Validator validator = schema.newValidator();
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.sdkuilib.repository;
|
||||||
|
|
||||||
|
import org.eclipse.swt.widgets.ProgressBar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A monitor interface for a {@link ProgressTask}
|
||||||
|
*/
|
||||||
|
interface ITaskMonitor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the description in the current task dialog.
|
||||||
|
* This method can be invoke from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void setDescription(String description);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the result text in the current task dialog.
|
||||||
|
* This method can be invoked from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void setResult(String result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the max value of the progress bar.
|
||||||
|
* This method can be invoke from a non-UI thread.
|
||||||
|
*
|
||||||
|
* @see ProgressBar#setMaximum(int)
|
||||||
|
*/
|
||||||
|
public void setProgressMax(int max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the current value of the progress bar.
|
||||||
|
*
|
||||||
|
* This method can be invoked from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void incProgress(int delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the "Cancel" button was selected.
|
||||||
|
* It is up to the task thread to pool this and exit.
|
||||||
|
*/
|
||||||
|
public boolean cancelRequested();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.sdkuilib.repository;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
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 org.eclipse.swt.widgets.Text;
|
||||||
|
|
||||||
|
class ProgressTask extends Dialog
|
||||||
|
implements ITaskMonitor //$hide$ (hide from SWT designer)
|
||||||
|
{
|
||||||
|
|
||||||
|
private boolean mCancelRequested;
|
||||||
|
private boolean mCloseRequested;
|
||||||
|
private boolean mAutomaticallyCloseOnTaskCompletion = true;
|
||||||
|
|
||||||
|
|
||||||
|
// UI fields
|
||||||
|
private Shell mDialogShell;
|
||||||
|
private Composite mRootComposite;
|
||||||
|
private Label mLabel;
|
||||||
|
private ProgressBar mProgressBar;
|
||||||
|
private Button mCancelButton;
|
||||||
|
private Text mResultText;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the dialog.
|
||||||
|
* @param parent Parent container
|
||||||
|
*/
|
||||||
|
public ProgressTask(Shell parent) {
|
||||||
|
super(parent, SWT.APPLICATION_MODAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the dialog and blocks till it gets closed
|
||||||
|
*/
|
||||||
|
public void open() {
|
||||||
|
createContents();
|
||||||
|
mDialogShell.open();
|
||||||
|
mDialogShell.layout();
|
||||||
|
Display display = getParent().getDisplay();
|
||||||
|
|
||||||
|
startTask(); //$hide$ (hide from SWT designer)
|
||||||
|
|
||||||
|
while (!mDialogShell.isDisposed() && !mCloseRequested) {
|
||||||
|
if (!display.readAndDispatch()) {
|
||||||
|
display.sleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mDialogShell.isDisposed()) {
|
||||||
|
mDialogShell.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create contents of the dialog.
|
||||||
|
*/
|
||||||
|
private void createContents() {
|
||||||
|
mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
|
||||||
|
mDialogShell.setLayout(new GridLayout(1, false));
|
||||||
|
mDialogShell.setSize(450, 300);
|
||||||
|
mDialogShell.setText(getText());
|
||||||
|
|
||||||
|
mRootComposite = new Composite(mDialogShell, SWT.NONE);
|
||||||
|
mRootComposite.setLayout(new GridLayout(2, false));
|
||||||
|
mRootComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
||||||
|
|
||||||
|
mLabel = new Label(mRootComposite, SWT.NONE);
|
||||||
|
mLabel.setText("Task");
|
||||||
|
mLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
|
||||||
|
|
||||||
|
mProgressBar = new ProgressBar(mRootComposite, SWT.NONE);
|
||||||
|
mProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
|
||||||
|
mCancelButton = new Button(mRootComposite, SWT.NONE);
|
||||||
|
mCancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
|
||||||
|
mCancelButton.setText("Cancel");
|
||||||
|
|
||||||
|
mCancelButton.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
mCancelRequested = true;
|
||||||
|
mCancelButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mResultText = new Text(mRootComposite,
|
||||||
|
SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL | SWT.MULTI);
|
||||||
|
mResultText.setEditable(true);
|
||||||
|
mResultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
|
||||||
|
mResultText.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- End of UI, Start of internal logic ----------
|
||||||
|
// Hide everything down-below from SWT designer
|
||||||
|
//$hide>>$
|
||||||
|
|
||||||
|
public interface ThreadTask {
|
||||||
|
public abstract void PerformTask(ITaskMonitor monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThreadTask mTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link ProgressTask} with the given title.
|
||||||
|
* The given task will execute in a separate thread (not the UI thread).
|
||||||
|
*
|
||||||
|
* This blocks till the thread ends.
|
||||||
|
*/
|
||||||
|
public static ProgressTask start(Shell parent, String title, ThreadTask task) {
|
||||||
|
ProgressTask t = new ProgressTask(parent);
|
||||||
|
t.setText(title);
|
||||||
|
t.setTask(task);
|
||||||
|
t.open();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the description in the current task dialog.
|
||||||
|
* This method can be invoke from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
mDialogShell.getDisplay().asyncExec(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!mLabel.isDisposed()) {
|
||||||
|
mLabel.setText(description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the description in the current task dialog.
|
||||||
|
* This method can be invoke from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void setResult(final String result) {
|
||||||
|
mAutomaticallyCloseOnTaskCompletion = false;
|
||||||
|
mDialogShell.getDisplay().asyncExec(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!mResultText.isDisposed()) {
|
||||||
|
mResultText.setVisible(true);
|
||||||
|
mResultText.setText(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the max value of the progress bar.
|
||||||
|
* This method can be invoke from a non-UI thread.
|
||||||
|
*
|
||||||
|
* @see ProgressBar#setMaximum(int)
|
||||||
|
*/
|
||||||
|
public void setProgressMax(final int max) {
|
||||||
|
mDialogShell.getDisplay().asyncExec(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!mProgressBar.isDisposed()) {
|
||||||
|
mProgressBar.setMaximum(max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the current value of the progress bar.
|
||||||
|
*
|
||||||
|
* This method can be invoked from a non-UI thread.
|
||||||
|
*/
|
||||||
|
public void incProgress(final int delta) {
|
||||||
|
mDialogShell.getDisplay().asyncExec(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!mProgressBar.isDisposed()) {
|
||||||
|
mProgressBar.setSelection(mProgressBar.getSelection() + delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the "Cancel" button was selected.
|
||||||
|
* It is up to the task thread to pool this and exit.
|
||||||
|
*/
|
||||||
|
public boolean cancelRequested() {
|
||||||
|
return mCancelRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the task that will execute in a separate thread. */
|
||||||
|
private void setTask(ThreadTask task) {
|
||||||
|
mTask = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the task from {@link #setTask(ThreadTask)} in a separate thread.
|
||||||
|
* When the task completes, set {@link #mCloseRequested} to end the dialog loop.
|
||||||
|
*/
|
||||||
|
private void startTask() {
|
||||||
|
if (mTask != null) {
|
||||||
|
new Thread(getText()) {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mTask.PerformTask(ProgressTask.this);
|
||||||
|
if (mAutomaticallyCloseOnTaskCompletion) {
|
||||||
|
mCloseRequested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//$hide<<$
|
||||||
|
}
|
||||||
@@ -0,0 +1,316 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.sdkuilib.repository;
|
||||||
|
|
||||||
|
import com.android.sdklib.repository.SdkRepository;
|
||||||
|
import com.android.sdkuilib.repository.ProgressTask.ThreadTask;
|
||||||
|
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
import javax.xml.validation.SchemaFactory;
|
||||||
|
import javax.xml.validation.Validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RepoSource {
|
||||||
|
|
||||||
|
private final String mUrl;
|
||||||
|
private final boolean mAddonOnly;
|
||||||
|
|
||||||
|
private ArrayList<String> mPackages;
|
||||||
|
private String mDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new source for the given repository URL.
|
||||||
|
*/
|
||||||
|
public RepoSource(String url, boolean addonOnly) {
|
||||||
|
mUrl = url;
|
||||||
|
mAddonOnly = addonOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the URL of the source repository. */
|
||||||
|
public String getUrl() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of known packages. This is null when the source hasn't been loaded yet.
|
||||||
|
*/
|
||||||
|
public ArrayList<String> getPackages() {
|
||||||
|
return mPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return mDescription == null ? "" : mDescription; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to fetch the repository index for the given URL.
|
||||||
|
*/
|
||||||
|
public void load(Shell shell) {
|
||||||
|
|
||||||
|
ProgressTask.start(shell, "Init SDK Updater", new ThreadTask() {
|
||||||
|
public void PerformTask(ITaskMonitor monitor) {
|
||||||
|
monitor.setProgressMax(4);
|
||||||
|
|
||||||
|
monitor.setDescription(String.format("Fetching %1$s", mUrl));
|
||||||
|
monitor.incProgress(1);
|
||||||
|
|
||||||
|
String xml = fetchUrl(mUrl, monitor);
|
||||||
|
|
||||||
|
if (xml == null) {
|
||||||
|
mDescription = String.format("Failed to fetch URL %1$s", mUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.setDescription("Validate XML");
|
||||||
|
monitor.incProgress(1);
|
||||||
|
|
||||||
|
if (!validateXml(xml, monitor)) {
|
||||||
|
mDescription = String.format("Failed to validate XML at %1$s", mUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.setDescription("Parse XML");
|
||||||
|
monitor.incProgress(1);
|
||||||
|
parsePackages(xml, monitor);
|
||||||
|
|
||||||
|
// done
|
||||||
|
monitor.incProgress(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* References:
|
||||||
|
* Java URL Connection: http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html
|
||||||
|
* Java URL Reader: http://java.sun.com/docs/books/tutorial/networking/urls/readingURL.html
|
||||||
|
* Java set Proxy: http://java.sun.com/docs/books/tutorial/networking/urls/_setProxy.html
|
||||||
|
*/
|
||||||
|
private String fetchUrl(String urlString, ITaskMonitor monitor) {
|
||||||
|
URL url;
|
||||||
|
try {
|
||||||
|
url = new URL(urlString);
|
||||||
|
|
||||||
|
StringBuilder xml = new StringBuilder();
|
||||||
|
InputStream is = null;
|
||||||
|
BufferedReader br = null;
|
||||||
|
try {
|
||||||
|
is = url.openStream();
|
||||||
|
br = new BufferedReader(new InputStreamReader(is));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
xml.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return xml.toString();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (br != null) {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
monitor.setResult(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateXml(String xml, ITaskMonitor monitor) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Validator validator = getValidator();
|
||||||
|
validator.validate(new StreamSource(new StringReader(xml)));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (SAXException e) {
|
||||||
|
monitor.setResult(e.getMessage());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
monitor.setResult(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper method that returns a validator for our XSD */
|
||||||
|
private Validator getValidator() throws SAXException {
|
||||||
|
InputStream xsdStream = SdkRepository.getXsdStream();
|
||||||
|
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||||
|
|
||||||
|
// This may throw a SAX Exception if the schema itself is not a valid XSD
|
||||||
|
Schema schema = factory.newSchema(new StreamSource(xsdStream));
|
||||||
|
|
||||||
|
Validator validator = schema.newValidator();
|
||||||
|
|
||||||
|
return validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean parsePackages(String xml, ITaskMonitor monitor) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Document doc = getDocument(xml);
|
||||||
|
|
||||||
|
Node root = getFirstChild(doc, SdkRepository.NODE_SDK_REPOSITORY);
|
||||||
|
if (root != null) {
|
||||||
|
|
||||||
|
mPackages = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (Node child = root.getFirstChild();
|
||||||
|
child != null;
|
||||||
|
child = child.getNextSibling()) {
|
||||||
|
if (child.getNodeType() == Node.ELEMENT_NODE &&
|
||||||
|
child.getNamespaceURI().equals(SdkRepository.NS_SDK_REPOSITORY)) {
|
||||||
|
String name = child.getLocalName();
|
||||||
|
if (SdkRepository.NODE_ADD_ON.equals(name)) {
|
||||||
|
parseAddon(child, mPackages, monitor);
|
||||||
|
|
||||||
|
} else if (!mAddonOnly) {
|
||||||
|
if (SdkRepository.NODE_PLATFORM.equals(name)) {
|
||||||
|
parsePlatform(child, mPackages, monitor);
|
||||||
|
|
||||||
|
} else if (SdkRepository.NODE_DOC.equals(name)) {
|
||||||
|
parseDoc(child, mPackages, monitor);
|
||||||
|
|
||||||
|
} else if (SdkRepository.NODE_TOOL.equals(name)) {
|
||||||
|
parseTool(child, mPackages, monitor);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
monitor.setResult("Failed to create XML document builder for %1$s");
|
||||||
|
|
||||||
|
} catch (SAXException e) {
|
||||||
|
monitor.setResult("Failed to parse XML document %1$s");
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
monitor.setResult("Failed to read XML document");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getFirstChild(Node node, String xmlLocalName) {
|
||||||
|
|
||||||
|
for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||||
|
if (child.getNodeType() == Node.ELEMENT_NODE &&
|
||||||
|
child.getNamespaceURI().equals(SdkRepository.NS_SDK_REPOSITORY)) {
|
||||||
|
if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Document getDocument(String xml)
|
||||||
|
throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
factory.setIgnoringComments(true);
|
||||||
|
factory.setNamespaceAware(true);
|
||||||
|
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(new InputSource(new StringReader(xml)));
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseAddon(Node addon, ArrayList<String> packages, ITaskMonitor monitor) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String s = String.format("addon %1$s by %2$s, api %3$s, rev %4$s",
|
||||||
|
getFirstChild(addon, SdkRepository.NODE_NAME).getTextContent(),
|
||||||
|
getFirstChild(addon, SdkRepository.NODE_VENDOR).getTextContent(),
|
||||||
|
getFirstChild(addon, SdkRepository.NODE_API_LEVEL).getTextContent(),
|
||||||
|
getFirstChild(addon, SdkRepository.NODE_REVISION).getTextContent()
|
||||||
|
);
|
||||||
|
packages.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parsePlatform(Node platform, ArrayList<String> packages, ITaskMonitor monitor) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String s = String.format("platform %1$s, api %2$s, rev %3$s",
|
||||||
|
getFirstChild(platform, SdkRepository.NODE_VERSION).getTextContent(),
|
||||||
|
getFirstChild(platform, SdkRepository.NODE_API_LEVEL).getTextContent(),
|
||||||
|
getFirstChild(platform, SdkRepository.NODE_REVISION).getTextContent()
|
||||||
|
);
|
||||||
|
packages.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseDoc(Node doc, ArrayList<String> packages, ITaskMonitor monitor) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String s = String.format("doc for api %1$s, rev %2$s",
|
||||||
|
getFirstChild(doc, SdkRepository.NODE_API_LEVEL).getTextContent(),
|
||||||
|
getFirstChild(doc, SdkRepository.NODE_REVISION).getTextContent()
|
||||||
|
);
|
||||||
|
packages.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseTool(Node tool, ArrayList<String> packages, ITaskMonitor monitor) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String s = String.format("tool, rev %1$s",
|
||||||
|
getFirstChild(tool, SdkRepository.NODE_REVISION).getTextContent()
|
||||||
|
);
|
||||||
|
packages.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/org/documents/epl-v10.php
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.sdkuilib.repository;
|
||||||
|
|
||||||
|
import org.eclipse.jface.viewers.IContentProvider;
|
||||||
|
import org.eclipse.jface.viewers.ILabelProvider;
|
||||||
|
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||||
|
import org.eclipse.jface.viewers.LabelProvider;
|
||||||
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RepoSources {
|
||||||
|
|
||||||
|
private Shell mShell;
|
||||||
|
private ArrayList<RepoSource> mSources = new ArrayList<RepoSource>();
|
||||||
|
|
||||||
|
public RepoSources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShell(Shell shell) {
|
||||||
|
mShell = shell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(RepoSource source) {
|
||||||
|
mSources.add(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILabelProvider getLabelProvider() {
|
||||||
|
return new ViewerLabelProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IContentProvider getContentProvider() {
|
||||||
|
return new TreeContentProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
|
||||||
|
public class ViewerLabelProvider extends LabelProvider {
|
||||||
|
/** Returns null by default */
|
||||||
|
@Override
|
||||||
|
public Image getImage(Object element) {
|
||||||
|
return super.getImage(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the toString of the element. */
|
||||||
|
@Override
|
||||||
|
public String getText(Object element) {
|
||||||
|
return super.getText(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
|
||||||
|
private class TreeContentProvider implements ITreeContentProvider {
|
||||||
|
|
||||||
|
private Object mInput;
|
||||||
|
|
||||||
|
// Called when the viewer is disposed
|
||||||
|
public void dispose() {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the input is set or changed on the provider
|
||||||
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
|
mInput = newInput;
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to collect the root elements for the given input.
|
||||||
|
* The input here is a {@link RepoSources} object, this returns an array
|
||||||
|
* of {@link RepoSource}.
|
||||||
|
*/
|
||||||
|
public Object[] getElements(Object inputElement) {
|
||||||
|
return getChildren(inputElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the children of the given parent. This is requested on-demand as
|
||||||
|
* nodes are expanded.
|
||||||
|
*
|
||||||
|
* For a {@link RepoSources} object, returns an array of {@link RepoSource}.
|
||||||
|
* For a {@link RepoSource}, returns an array of packages.
|
||||||
|
*/
|
||||||
|
public Object[] getChildren(Object parentElement) {
|
||||||
|
if (parentElement instanceof RepoSources) {
|
||||||
|
return ((RepoSources) parentElement).mSources.toArray();
|
||||||
|
|
||||||
|
} else if (parentElement instanceof RepoSource) {
|
||||||
|
RepoSource source = (RepoSource) parentElement;
|
||||||
|
ArrayList<String> pkgs = source.getPackages();
|
||||||
|
|
||||||
|
if (pkgs == null) {
|
||||||
|
source.load(mShell);
|
||||||
|
pkgs = source.getPackages();
|
||||||
|
}
|
||||||
|
if (pkgs != null) {
|
||||||
|
return pkgs.toArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Object[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent of a given element.
|
||||||
|
* The input {@link RepoSources} is the parent of all {@link RepoSource} elements.
|
||||||
|
*/
|
||||||
|
public Object getParent(Object element) {
|
||||||
|
if (element instanceof RepoSource) {
|
||||||
|
return mInput;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a given element has children, which is used to display a
|
||||||
|
* "+/expand" box next to the tree node.
|
||||||
|
* All {@link RepoSource} are expandable, whether they actually have any childre or not.
|
||||||
|
*/
|
||||||
|
public boolean hasChildren(Object element) {
|
||||||
|
return element instanceof RepoSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,10 +16,14 @@
|
|||||||
|
|
||||||
package com.android.sdkuilib.repository;
|
package com.android.sdkuilib.repository;
|
||||||
|
|
||||||
|
import com.android.sdkuilib.repository.ProgressTask.ThreadTask;
|
||||||
|
|
||||||
import org.eclipse.jface.viewers.CheckboxTreeViewer;
|
import org.eclipse.jface.viewers.CheckboxTreeViewer;
|
||||||
import org.eclipse.jface.viewers.TableViewer;
|
import org.eclipse.jface.viewers.TableViewer;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.custom.TableTree;
|
import org.eclipse.swt.custom.TableTree;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.graphics.Point;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
@@ -39,40 +43,54 @@ import org.eclipse.swt.widgets.TreeColumn;
|
|||||||
|
|
||||||
public class UpdaterWindow {
|
public class UpdaterWindow {
|
||||||
|
|
||||||
protected Shell mshlAndroidSdkUpdater;
|
private final String mOsSdkRoot;
|
||||||
private TabFolder tabFolder;
|
private final boolean mUserCanChangeSdkRoot;
|
||||||
private TabItem mtbtmInstalledPackages;
|
|
||||||
private Composite compositeInst;
|
private RepoSources mSources = new RepoSources();
|
||||||
private TabItem mtbtmAvailablePackages;
|
|
||||||
private Composite compositeAvail;
|
// --- UI members ---
|
||||||
private Text text;
|
|
||||||
private Button mbtnBrowse;
|
protected Shell mAndroidSdkUpdater;
|
||||||
private Label mlblSdkLocation;
|
private TabFolder mTabFolder;
|
||||||
private Group mgrpDescription;
|
private TabItem mTabInstalledPkg;
|
||||||
private Composite composite_3;
|
private Composite mRootInst;
|
||||||
private Button mbtnUpdate;
|
private TabItem mTabAvailPkg;
|
||||||
private Button mbtnDelete;
|
private Composite mRootAvail;
|
||||||
private Button mbtnHomePage;
|
private Text mSdkLocText;
|
||||||
private Label placeholder1;
|
private Button mSdkLocBrowse;
|
||||||
private Label placeholder2;
|
private Label mSdkLocLabel;
|
||||||
private Label mlblInstalledPackages;
|
private Group mInstDescription;
|
||||||
|
private Composite mInstButtons;
|
||||||
|
private Button mInstUpdate;
|
||||||
|
private Button mInstDelete;
|
||||||
|
private Button mInstHomePage;
|
||||||
|
private Label mPlaceholder1;
|
||||||
|
private Label mPlaceholder2;
|
||||||
|
private Label mInstalledPkgLabel;
|
||||||
private TableTree tableTree;
|
private TableTree tableTree;
|
||||||
private Tree tree;
|
private Tree mTreeAvailPkg;
|
||||||
private Button mbtnRemoveSite;
|
private Button mAvailRemoveSite;
|
||||||
private Button mbtnAddSite;
|
private Button mAvailAddSite;
|
||||||
private Label placeholder3;
|
private Label mPlaceholder3;
|
||||||
private Button mbtnRefresh;
|
private Button mAvailRefresh;
|
||||||
private Button mbtnInstallSelected;
|
private Button mAvailInstallSelected;
|
||||||
private Group mgrpDescription_1;
|
private Group mAvailDescription;
|
||||||
private Table table;
|
private Table mTableInstPkg;
|
||||||
private TableColumn mtblclmnSummary;
|
private TableColumn mColumnInstSummary;
|
||||||
private TableColumn mtblclmnApiLevel;
|
private TableColumn mColumnInstApiLevel;
|
||||||
private TableColumn mtblclmnRevision;
|
private TableColumn mColumnInstRevision;
|
||||||
private TreeColumn mtrclmnSummary;
|
private TreeColumn mColumnAvailSummary;
|
||||||
private TreeColumn mtrclmnApiLevel;
|
private TreeColumn mColumnAvailApiLevel;
|
||||||
private TreeColumn mtrclmnRevision;
|
private TreeColumn mColumnAvailRevision;
|
||||||
private TreeColumn mtrclmnOs;
|
private TreeColumn mColumnAvailOs;
|
||||||
private TreeColumn mtrclmnInstalled;
|
private TreeColumn mColumnAvailInstalled;
|
||||||
|
private CheckboxTreeViewer mTreeViewAvailPkg;
|
||||||
|
private TableViewer mTableViewerInstPkg;
|
||||||
|
|
||||||
|
public UpdaterWindow(String osSdkRoot, boolean userCanChangeSdkRoot) {
|
||||||
|
mOsSdkRoot = osSdkRoot;
|
||||||
|
mUserCanChangeSdkRoot = userCanChangeSdkRoot;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the window.
|
* Open the window.
|
||||||
@@ -81,9 +99,10 @@ public class UpdaterWindow {
|
|||||||
public void open() {
|
public void open() {
|
||||||
Display display = Display.getDefault();
|
Display display = Display.getDefault();
|
||||||
createContents();
|
createContents();
|
||||||
mshlAndroidSdkUpdater.open();
|
mAndroidSdkUpdater.open();
|
||||||
mshlAndroidSdkUpdater.layout();
|
mAndroidSdkUpdater.layout();
|
||||||
while (!mshlAndroidSdkUpdater.isDisposed()) {
|
firstInit();
|
||||||
|
while (!mAndroidSdkUpdater.isDisposed()) {
|
||||||
if (!display.readAndDispatch()) {
|
if (!display.readAndDispatch()) {
|
||||||
display.sleep();
|
display.sleep();
|
||||||
}
|
}
|
||||||
@@ -94,129 +113,212 @@ public class UpdaterWindow {
|
|||||||
* Create contents of the window.
|
* Create contents of the window.
|
||||||
*/
|
*/
|
||||||
protected void createContents() {
|
protected void createContents() {
|
||||||
mshlAndroidSdkUpdater = new Shell();
|
mAndroidSdkUpdater = new Shell();
|
||||||
mshlAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
|
mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
|
||||||
mshlAndroidSdkUpdater.setLayout(new GridLayout(1, false));
|
mAndroidSdkUpdater.setLayout(new GridLayout(1, false));
|
||||||
mshlAndroidSdkUpdater.setSize(633, 433);
|
mAndroidSdkUpdater.setSize(633, 433);
|
||||||
mshlAndroidSdkUpdater.setText("Android SDK Updater");
|
mAndroidSdkUpdater.setText("Android SDK Updater");
|
||||||
|
|
||||||
tabFolder = new TabFolder(mshlAndroidSdkUpdater, SWT.NONE);
|
mTabFolder = new TabFolder(mAndroidSdkUpdater, SWT.NONE);
|
||||||
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
mTabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
||||||
|
|
||||||
mtbtmInstalledPackages = new TabItem(tabFolder, SWT.NONE);
|
createInstalledPackagesTab();
|
||||||
mtbtmInstalledPackages.setText("Installed Packages");
|
createAvailablePackagesTab();
|
||||||
|
}
|
||||||
|
|
||||||
compositeInst = new Composite(tabFolder, SWT.NONE);
|
private void createInstalledPackagesTab() {
|
||||||
compositeInst.setLayout(new GridLayout(3, false));
|
mTabInstalledPkg = new TabItem(mTabFolder, SWT.NONE);
|
||||||
mtbtmInstalledPackages.setControl(compositeInst);
|
mTabInstalledPkg.setText("Installed Packages");
|
||||||
|
|
||||||
mlblSdkLocation = new Label(compositeInst, SWT.NONE);
|
mRootInst = new Composite(mTabFolder, SWT.NONE);
|
||||||
mlblSdkLocation.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
|
mRootInst.setLayout(new GridLayout(3, false));
|
||||||
mlblSdkLocation.setText("SDK Location:");
|
mTabInstalledPkg.setControl(mRootInst);
|
||||||
|
|
||||||
text = new Text(compositeInst, SWT.BORDER);
|
createSdkLocation();
|
||||||
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
|
|
||||||
|
|
||||||
mbtnBrowse = new Button(compositeInst, SWT.NONE);
|
mInstalledPkgLabel = new Label(mRootInst, SWT.NONE);
|
||||||
mbtnBrowse.setText("Browse...");
|
mInstalledPkgLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
|
||||||
|
mInstalledPkgLabel.setText("Installed Packages:");
|
||||||
|
|
||||||
mlblInstalledPackages = new Label(compositeInst, SWT.NONE);
|
mTableViewerInstPkg = new TableViewer(mRootInst, SWT.BORDER | SWT.FULL_SELECTION);
|
||||||
mlblInstalledPackages.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
|
mTableInstPkg = mTableViewerInstPkg.getTable();
|
||||||
mlblInstalledPackages.setText("Installed Packages:");
|
mTableInstPkg.setHeaderVisible(true);
|
||||||
|
mTableInstPkg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
|
||||||
|
|
||||||
TableViewer tableInstalledPackage = new TableViewer(compositeInst, SWT.BORDER | SWT.FULL_SELECTION);
|
mColumnInstSummary = new TableColumn(mTableInstPkg, SWT.NONE);
|
||||||
table = tableInstalledPackage.getTable();
|
mColumnInstSummary.setWidth(377);
|
||||||
table.setHeaderVisible(true);
|
mColumnInstSummary.setText("Summary");
|
||||||
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
|
|
||||||
|
|
||||||
mtblclmnSummary = new TableColumn(table, SWT.NONE);
|
mColumnInstApiLevel = new TableColumn(mTableInstPkg, SWT.NONE);
|
||||||
mtblclmnSummary.setWidth(377);
|
mColumnInstApiLevel.setWidth(100);
|
||||||
mtblclmnSummary.setText("Summary");
|
mColumnInstApiLevel.setText("API Level");
|
||||||
|
|
||||||
mtblclmnApiLevel = new TableColumn(table, SWT.NONE);
|
mColumnInstRevision = new TableColumn(mTableInstPkg, SWT.NONE);
|
||||||
mtblclmnApiLevel.setWidth(100);
|
mColumnInstRevision.setWidth(100);
|
||||||
mtblclmnApiLevel.setText("API Level");
|
mColumnInstRevision.setText("Revision");
|
||||||
|
|
||||||
mtblclmnRevision = new TableColumn(table, SWT.NONE);
|
mInstDescription = new Group(mRootInst, SWT.NONE);
|
||||||
mtblclmnRevision.setWidth(100);
|
mInstDescription.setText("Description");
|
||||||
mtblclmnRevision.setText("Revision");
|
mInstDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
|
||||||
|
|
||||||
mgrpDescription = new Group(compositeInst, SWT.NONE);
|
mInstButtons = new Composite(mRootInst, SWT.NONE);
|
||||||
mgrpDescription.setText("Description");
|
mInstButtons.setLayout(new GridLayout(5, false));
|
||||||
mgrpDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
|
mInstButtons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
|
||||||
|
|
||||||
composite_3 = new Composite(compositeInst, SWT.NONE);
|
mInstUpdate = new Button(mInstButtons, SWT.NONE);
|
||||||
composite_3.setLayout(new GridLayout(5, false));
|
mInstUpdate.addSelectionListener(new SelectionAdapter() {
|
||||||
composite_3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
onUpdateInstalledPackage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mInstUpdate.setText("Update...");
|
||||||
|
|
||||||
mbtnUpdate = new Button(composite_3, SWT.NONE);
|
mPlaceholder1 = new Label(mInstButtons, SWT.NONE);
|
||||||
mbtnUpdate.setText("Update...");
|
mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
|
||||||
|
|
||||||
placeholder1 = new Label(composite_3, SWT.NONE);
|
mInstDelete = new Button(mInstButtons, SWT.NONE);
|
||||||
placeholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
|
mInstDelete.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
|
||||||
|
mInstDelete.setText("Delete...");
|
||||||
|
|
||||||
mbtnDelete = new Button(composite_3, SWT.NONE);
|
mPlaceholder2 = new Label(mInstButtons, SWT.NONE);
|
||||||
mbtnDelete.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
|
mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
|
||||||
mbtnDelete.setText("Delete...");
|
|
||||||
|
|
||||||
placeholder2 = new Label(composite_3, SWT.NONE);
|
mInstHomePage = new Button(mInstButtons, SWT.NONE);
|
||||||
placeholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
|
mInstHomePage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
|
||||||
|
mInstHomePage.setText("Home Page...");
|
||||||
|
}
|
||||||
|
|
||||||
mbtnHomePage = new Button(composite_3, SWT.NONE);
|
private void createSdkLocation() {
|
||||||
mbtnHomePage.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
|
mSdkLocLabel = new Label(mRootInst, SWT.NONE);
|
||||||
mbtnHomePage.setText("Home Page...");
|
mSdkLocLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
|
||||||
|
mSdkLocLabel.setText("SDK Location:");
|
||||||
|
|
||||||
mtbtmAvailablePackages = new TabItem(tabFolder, SWT.NONE);
|
// If the sdk path is not user-customizable, do not create
|
||||||
mtbtmAvailablePackages.setText("Available Packages");
|
// the browse button and use horizSpan=2 on the text field.
|
||||||
|
|
||||||
compositeAvail = new Composite(tabFolder, SWT.NONE);
|
mSdkLocText = new Text(mRootInst, SWT.BORDER);
|
||||||
compositeAvail.setLayout(new GridLayout(5, false));
|
mSdkLocText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
|
||||||
mtbtmAvailablePackages.setControl(compositeAvail);
|
|
||||||
|
|
||||||
CheckboxTreeViewer checkboxTreeAvailablePackages = new CheckboxTreeViewer(compositeAvail, SWT.BORDER);
|
if (mUserCanChangeSdkRoot) {
|
||||||
tree = checkboxTreeAvailablePackages.getTree();
|
mSdkLocBrowse = new Button(mRootInst, SWT.NONE);
|
||||||
tree.setHeaderVisible(true);
|
mSdkLocBrowse.setText("Browse...");
|
||||||
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
|
} else {
|
||||||
|
mSdkLocText.setEditable(false);
|
||||||
|
((GridData)mSdkLocText.getLayoutData()).horizontalSpan++;
|
||||||
|
}
|
||||||
|
|
||||||
mtrclmnSummary = new TreeColumn(tree, SWT.NONE);
|
mSdkLocText.setText(mOsSdkRoot);
|
||||||
mtrclmnSummary.setWidth(289);
|
}
|
||||||
mtrclmnSummary.setText("Summary");
|
|
||||||
|
|
||||||
mtrclmnApiLevel = new TreeColumn(tree, SWT.NONE);
|
private void createAvailablePackagesTab() {
|
||||||
mtrclmnApiLevel.setWidth(66);
|
mTabAvailPkg = new TabItem(mTabFolder, SWT.NONE);
|
||||||
mtrclmnApiLevel.setText("API Level");
|
mTabAvailPkg.setText("Available Packages");
|
||||||
|
|
||||||
mtrclmnRevision = new TreeColumn(tree, SWT.NONE);
|
mRootAvail = new Composite(mTabFolder, SWT.NONE);
|
||||||
mtrclmnRevision.setWidth(63);
|
mRootAvail.setLayout(new GridLayout(5, false));
|
||||||
mtrclmnRevision.setText("Revision");
|
mTabAvailPkg.setControl(mRootAvail);
|
||||||
|
|
||||||
mtrclmnOs = new TreeColumn(tree, SWT.NONE);
|
mTreeViewAvailPkg = new CheckboxTreeViewer(mRootAvail, SWT.BORDER);
|
||||||
mtrclmnOs.setWidth(100);
|
mTreeViewAvailPkg.setContentProvider(mSources.getContentProvider());
|
||||||
mtrclmnOs.setText("OS/Arch");
|
mTreeViewAvailPkg.setLabelProvider(mSources.getLabelProvider());
|
||||||
|
mTreeAvailPkg = mTreeViewAvailPkg.getTree();
|
||||||
|
mTreeAvailPkg.setHeaderVisible(true);
|
||||||
|
mTreeAvailPkg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
|
||||||
|
|
||||||
mtrclmnInstalled = new TreeColumn(tree, SWT.NONE);
|
mColumnAvailSummary = new TreeColumn(mTreeAvailPkg, SWT.NONE);
|
||||||
mtrclmnInstalled.setWidth(59);
|
mColumnAvailSummary.setWidth(289);
|
||||||
mtrclmnInstalled.setText("Installed");
|
mColumnAvailSummary.setText("Summary");
|
||||||
|
|
||||||
mgrpDescription_1 = new Group(compositeAvail, SWT.NONE);
|
mColumnAvailApiLevel = new TreeColumn(mTreeAvailPkg, SWT.NONE);
|
||||||
mgrpDescription_1.setText("Description");
|
mColumnAvailApiLevel.setWidth(66);
|
||||||
mgrpDescription_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 5, 1));
|
mColumnAvailApiLevel.setText("API Level");
|
||||||
|
|
||||||
mbtnAddSite = new Button(compositeAvail, SWT.NONE);
|
mColumnAvailRevision = new TreeColumn(mTreeAvailPkg, SWT.NONE);
|
||||||
mbtnAddSite.setText("Add Site...");
|
mColumnAvailRevision.setWidth(63);
|
||||||
|
mColumnAvailRevision.setText("Revision");
|
||||||
|
|
||||||
mbtnRemoveSite = new Button(compositeAvail, SWT.NONE);
|
mColumnAvailOs = new TreeColumn(mTreeAvailPkg, SWT.NONE);
|
||||||
mbtnRemoveSite.setText("Delete Site...");
|
mColumnAvailOs.setWidth(100);
|
||||||
|
mColumnAvailOs.setText("OS/Arch");
|
||||||
|
|
||||||
placeholder3 = new Label(compositeAvail, SWT.NONE);
|
mColumnAvailInstalled = new TreeColumn(mTreeAvailPkg, SWT.NONE);
|
||||||
placeholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
|
mColumnAvailInstalled.setWidth(59);
|
||||||
|
mColumnAvailInstalled.setText("Installed");
|
||||||
|
|
||||||
mbtnRefresh = new Button(compositeAvail, SWT.NONE);
|
mAvailDescription = new Group(mRootAvail, SWT.NONE);
|
||||||
mbtnRefresh.setText("Refresh");
|
mAvailDescription.setText("Description");
|
||||||
|
mAvailDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 5, 1));
|
||||||
|
|
||||||
mbtnInstallSelected = new Button(compositeAvail, SWT.NONE);
|
mAvailAddSite = new Button(mRootAvail, SWT.NONE);
|
||||||
mbtnInstallSelected.setText("Install Selected");
|
mAvailAddSite.setText("Add Site...");
|
||||||
|
|
||||||
|
mAvailRemoveSite = new Button(mRootAvail, SWT.NONE);
|
||||||
|
mAvailRemoveSite.setText("Delete Site...");
|
||||||
|
|
||||||
|
mPlaceholder3 = new Label(mRootAvail, SWT.NONE);
|
||||||
|
mPlaceholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
|
||||||
|
|
||||||
|
mAvailRefresh = new Button(mRootAvail, SWT.NONE);
|
||||||
|
mAvailRefresh.setText("Refresh");
|
||||||
|
|
||||||
|
mAvailInstallSelected = new Button(mRootAvail, SWT.NONE);
|
||||||
|
mAvailInstallSelected.setText("Install Selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UI Callbacks -----------
|
||||||
|
|
||||||
|
protected void onUpdateInstalledPackage() {
|
||||||
|
ProgressTask.start(getShell(), "Test", new ThreadTask() {
|
||||||
|
public void PerformTask(ITaskMonitor monitor) {
|
||||||
|
monitor.setDescription("Test");
|
||||||
|
monitor.setProgressMax(100);
|
||||||
|
int n = 0;
|
||||||
|
int d = 1;
|
||||||
|
while(!monitor.cancelRequested()) {
|
||||||
|
monitor.incProgress(d);
|
||||||
|
n += d;
|
||||||
|
if (n == 0 || n == 100) d = -d;
|
||||||
|
try {
|
||||||
|
Thread.sleep(5);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------
|
||||||
|
|
||||||
|
private Shell getShell() {
|
||||||
|
return mAndroidSdkUpdater;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Once the UI has been created, initialize the content
|
||||||
|
*/
|
||||||
|
private void firstInit() {
|
||||||
|
|
||||||
|
setupSources();
|
||||||
|
scanLocalSdkFolders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSources() {
|
||||||
|
mSources.setShell(getShell());
|
||||||
|
|
||||||
|
mSources.add(new RepoSource(
|
||||||
|
"https://dl.google.com/android/eclipse/repository/index.xml", //$NON-NLS-1$
|
||||||
|
false /* addonOnly */));
|
||||||
|
mSources.add(new RepoSource(
|
||||||
|
"http://www.corp.google.com/~raphael/android/sdk-repo/repository.xml", //$NON-NLS-1$
|
||||||
|
false /* addonOnly */));
|
||||||
|
|
||||||
|
mTreeViewAvailPkg.setInput(mSources);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanLocalSdkFolders() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user