Merge change 2300 into donut

* changes:
  SDK Updater: some refactoring and some new features.
This commit is contained in:
Android (Google) Code Review
2009-05-22 12:30:35 -07:00
23 changed files with 1096 additions and 456 deletions

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node;
/**
*
*/
public class AddonPackage extends Package {
private final String mVendor;
private final String mName;
private final String mApiLevel;
public AddonPackage(Node packageNode) {
super(packageNode);
mVendor = getXmlString(packageNode, SdkRepository.NODE_VENDOR);
mName = getXmlString(packageNode, SdkRepository.NODE_NAME);
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL);
// TODO libs
}
public String getVendor() {
return mVendor;
}
public String getName() {
return mName;
}
public String getApiLevel() {
return mApiLevel;
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import org.w3c.dom.Node;
/**
*
*/
public class DocPackage extends Package {
public DocPackage(Node packageNode) {
super(packageNode);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
/**
* Interface for elements that can provide a description of themselves.
*/
public interface IDescription {
/**
* Returns a description of the given element. Cannot be null.
* <p/>
* A description is a multi-line of text, typically much more
* elaborate than what {@link #toString()} would provide.
*/
public abstract String getShortDescription();
/**
* Returns a description of the given element. Cannot be null.
* <p/>
* A description is a multi-line of text, typically much more
* elaborate than what {@link #toString()} would provide.
*/
public abstract String getLongDescription();
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
/**
* A task that executes and can update a monitor to display its status.
* The task will generally be run in a separate thread.
*/
public interface ITask {
public abstract void run(ITaskMonitor monitor);
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
/**
* A factory that can start and run new {@link ITask}s.
*/
public interface ITaskFactory {
public abstract void start(String title, ITask task);
}

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,18 +14,25 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.sdkuilib.repository; package com.android.sdklib.internal.repository;
import org.eclipse.swt.widgets.ProgressBar;
/** /**
* A monitor interface for a {@link ProgressTask} * A monitor interface for a {@link ITask}.
* <p/>
* Depending on the task factory that created the task, there might not be any UI
* or it might not implement all the methods, in which case calling them would be
* a no-op but is guaranteed not to crash.
* <p/>
* If the task runs in a non-UI worker thread, the task factory implementation
* will take care of the update the UI in the correct thread. The task itself
* must not have to deal with it.
*/ */
interface ITaskMonitor { public interface ITaskMonitor {
/** /**
* Sets the description in the current task dialog. * Sets the description in the current task dialog.
* This method can be invoke from a non-UI thread. * This method can be invoked from a non-UI thread.
*/ */
public void setDescription(String description); public void setDescription(String description);
@@ -37,24 +44,20 @@ interface ITaskMonitor {
/** /**
* Sets the max value of the progress bar. * Sets the max value of the progress bar.
* This method can be invoke from a non-UI thread. * This method can be invoked from a non-UI thread.
*
* @see ProgressBar#setMaximum(int)
*/ */
public void setProgressMax(int max); public void setProgressMax(int max);
/** /**
* Increments the current value of the progress bar. * Increments the current value of the progress bar.
*
* This method can be invoked from a non-UI thread. * This method can be invoked from a non-UI thread.
*/ */
public void incProgress(int delta); public void incProgress(int delta);
/** /**
* Returns true if the "Cancel" button was selected. * Returns true if the user requested to cancel the operation.
* It is up to the task thread to pool this and exit. * It is up to the task thread to pool this and exit as soon
* as possible.
*/ */
public boolean cancelRequested(); public boolean cancelRequested();
} }

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node;
/**
*
*/
public class Package {
private final int mRevision;
private final String mDescription;
private final String mDescUrl;
private Package(int revision, String description, String descUrl) {
mRevision = revision;
mDescription = description;
mDescUrl = descUrl;
}
public Package(Node packageNode) {
this(getXmlInt (packageNode, SdkRepository.NODE_REVISION, 0),
getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION),
getXmlString(packageNode, SdkRepository.NODE_DESC_URL));
// TODO archives
}
/** The revision, an int > 0, for all packages (platform, add-on, tool, doc). */
public int getRevision() {
return mRevision;
}
/** The optional description for all packages (platform, add-on, tool, doc) or for a lib. */
public String getDescription() {
return mDescription;
}
/** The optional description URL for all packages (platform, add-on, tool, doc).
* Can be empty but not null. */
public String getDescUrl() {
return mDescUrl;
}
/**
* Retrieves the value of that XML element as a string.
* Returns an empty string when the element is missing.
*/
protected static String getXmlString(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.getTextContent();
}
}
}
return "";
}
/**
* Retrieves the value of that XML element as an integer.
* Returns the default value when the element is missing or is not an integer.
*/
protected static int getXmlInt(Node node, String xmlLocalName, int defaultValue) {
String s = getXmlString(node, xmlLocalName);
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node;
/**
*
*/
public class PlatformPackage extends Package {
private final String mVersion;
private final String mApiLevel;
public PlatformPackage(Node packageNode) {
super(packageNode);
mVersion = getXmlString(packageNode, SdkRepository.NODE_VERSION);
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL);
}
public String getVersion() {
return mVersion;
}
public String getApiLevel() {
return mApiLevel;
}
}

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.sdkuilib.repository; package com.android.sdklib.internal.repository;
import com.android.sdklib.repository.SdkRepository; 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.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@@ -43,9 +41,9 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
/** /**
* * An sdk-repository source. It may be a full repository or an add-on only repository.
*/ */
class RepoSource { public class RepoSource implements IDescription {
private final String mUrl; private final String mUrl;
private final boolean mAddonOnly; private final boolean mAddonOnly;
@@ -59,11 +57,7 @@ class RepoSource {
public RepoSource(String url, boolean addonOnly) { public RepoSource(String url, boolean addonOnly) {
mUrl = url; mUrl = url;
mAddonOnly = addonOnly; mAddonOnly = addonOnly;
} setDefaultDescription();
@Override
public String toString() {
return mUrl;
} }
/** Returns the URL of the source repository. */ /** Returns the URL of the source repository. */
@@ -78,26 +72,32 @@ class RepoSource {
return mPackages; return mPackages;
} }
public String getDescription() { public String getShortDescription() {
return mUrl;
}
public String getLongDescription() {
return mDescription == null ? "" : mDescription; //$NON-NLS-1$ return mDescription == null ? "" : mDescription; //$NON-NLS-1$
} }
/** /**
* Tries to fetch the repository index for the given URL. * Tries to fetch the repository index for the given URL.
*/ */
public void load(Shell shell) { public void load(ITaskFactory taskFactory) {
ProgressTask.start(shell, "Init SDK Updater", new ThreadTask() { taskFactory.start("Init SDK Updater", new ITask() {
public void PerformTask(ITaskMonitor monitor) { public void run(ITaskMonitor monitor) {
monitor.setProgressMax(4); monitor.setProgressMax(4);
setDefaultDescription();
monitor.setDescription(String.format("Fetching %1$s", mUrl)); monitor.setDescription(String.format("Fetching %1$s", mUrl));
monitor.incProgress(1); monitor.incProgress(1);
String xml = fetchUrl(mUrl, monitor); String xml = fetchUrl(mUrl, monitor);
if (xml == null) { if (xml == null) {
mDescription = String.format("Failed to fetch URL %1$s", mUrl); mDescription += String.format("\nFailed to fetch URL %1$s", mUrl);
return; return;
} }
@@ -105,13 +105,20 @@ class RepoSource {
monitor.incProgress(1); monitor.incProgress(1);
if (!validateXml(xml, monitor)) { if (!validateXml(xml, monitor)) {
mDescription = String.format("Failed to validate XML at %1$s", mUrl); mDescription += String.format("\nFailed to validate XML at %1$s", mUrl);
return; return;
} }
monitor.setDescription("Parse XML"); monitor.setDescription("Parse XML");
monitor.incProgress(1); monitor.incProgress(1);
parsePackages(xml, monitor); parsePackages(xml, monitor);
if (mPackages.size() == 0) {
mDescription += "\nNo packages found.";
} else if (mPackages.size() == 1) {
mDescription += "\nOne package found.";
} else {
mDescription += String.format("\n%1$d packages found.", mPackages.size());
}
// done // done
monitor.incProgress(1); monitor.incProgress(1);
@@ -119,6 +126,14 @@ class RepoSource {
}); });
} }
private void setDefaultDescription() {
if (mAddonOnly) {
mDescription = String.format("Add-on Source: %1$s", mUrl);
} else {
mDescription = String.format("SDK Source: %1$s", mUrl);
}
}
/* /*
* References: * References:
* Java URL Connection: http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html * Java URL Connection: http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.repository.SdkRepository;
import org.w3c.dom.Node;
/**
*
*/
public class ToolPackage extends Package {
private final String mApiLevel;
public ToolPackage(Node packageNode) {
super(packageNode);
mApiLevel = getXmlString(packageNode, SdkRepository.NODE_API_LEVEL);
}
public String getApiLevel() {
return mApiLevel;
}
}

View File

@@ -19,24 +19,64 @@ package com.android.sdklib.repository;
import java.io.InputStream; import java.io.InputStream;
/** /**
* Constants for the sdk-repository XML Schema * Public constants for the sdk-repository XML Schema.
*/ */
public class SdkRepository { public class SdkRepository {
/** The XML namespace of the sdk-repository XML. */
public static final String NS_SDK_REPOSITORY = public static final String NS_SDK_REPOSITORY =
"http://schemas.android.com/sdk/android/repository/1"; //$NON-NLS-1$ "http://schemas.android.com/sdk/android/repository/1"; //$NON-NLS-1$
public static final String NODE_VERSION = "version"; //$NON-NLS-1$ /** The root sdk-repository element */
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 final String NODE_SDK_REPOSITORY = "sdk-repository"; //$NON-NLS-1$
/** A platform package. */
public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$
/** An add-on package. */
public static final String NODE_ADD_ON = "add-on"; //$NON-NLS-1$
/** A tool package. */
public static final String NODE_TOOL = "tool"; //$NON-NLS-1$
/** A doc package. */
public static final String NODE_DOC = "doc"; //$NON-NLS-1$
/** The revision, an int > 0, for all packages (platform, add-on, tool, doc). */
public static final String NODE_REVISION = "revision"; //$NON-NLS-1$
/** The optional description for all packages (platform, add-on, tool, doc) or for a lib. */
public static final String NODE_DESCRIPTION = "description"; //$NON-NLS-1$
/** The optional description URL for all packages (platform, add-on, tool, doc). */
public static final String NODE_DESC_URL = "desc-url"; //$NON-NLS-1$
/** The version, a string, for platform packages. */
public static final String NODE_VERSION = "version"; //$NON-NLS-1$
/** The api-level, an int > 0, for platform, add-on and doc packages. */
public static final String NODE_API_LEVEL = "api-level"; //$NON-NLS-1$
/** The vendor, a string, for add-on packages. */
public static final String NODE_VENDOR = "vendor"; //$NON-NLS-1$
/** The name, a string, for add-on packages or for libraries. */
public static final String NODE_NAME = "name"; //$NON-NLS-1$
/** The libs container, optional for an add-on. */
public static final String NODE_LIBS = "libs"; //$NON-NLS-1$
/** A lib element in a libs container. */
public static final String NODE_LIB = "lib"; //$NON-NLS-1$
/** The archives container, for all packages. */
public static final String NODE_ARCHVIES = "archives"; //$NON-NLS-1$
/** An archive element, for the archives container. */
public static final String NODE_ARCHVIE = "archive"; //$NON-NLS-1$
/** An archive size, an int > 0. */
public static final String NODE_SIZE = "size"; //$NON-NLS-1$
/** A sha1 archive checksum, as a 40-char hex. */
public static final String NODE_CHECKSUM = "checksum"; //$NON-NLS-1$
/** A download archive URL, either absolute or relative to the repository xml. */
public static final String NODE_URL = "url"; //$NON-NLS-1$
/** An archive OS attribute, mandatory. */
public static final String NODE_OS = "os"; //$NON-NLS-1$
/** An optional archive Architecture attribute. */
public static final String NODE_ARCH = "arch"; //$NON-NLS-1$
public static InputStream getXsdStream() { public static InputStream getXsdStream() {
return SdkRepository.class.getResourceAsStream("sdk-repository.xsd"); //$NON-NLS-1$ return SdkRepository.class.getResourceAsStream("sdk-repository.xsd"); //$NON-NLS-1$
} }

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -46,17 +46,17 @@ import org.eclipse.swt.widgets.TableItem;
* selection. * selection.
*/ */
public class SdkTargetSelector { public class SdkTargetSelector {
private IAndroidTarget[] mTargets; private IAndroidTarget[] mTargets;
private final boolean mAllowSelection; private final boolean mAllowSelection;
private SelectionListener mSelectionListener; private SelectionListener mSelectionListener;
private Table mTable; private Table mTable;
private Label mDescription; private Label mDescription;
private Composite mInnerGroup; private Composite mInnerGroup;
/** /**
* Creates a new SDK Target Selector. * Creates a new SDK Target Selector.
* *
* @param parent The parent composite where the selector will be added. * @param parent The parent composite where the selector will be added.
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
* Targets can be null or an empty array, in which case the table is disabled. * Targets can be null or an empty array, in which case the table is disabled.
@@ -67,7 +67,7 @@ public class SdkTargetSelector {
/** /**
* Creates a new SDK Target Selector. * Creates a new SDK Target Selector.
* *
* @param parent The parent composite where the selector will be added. * @param parent The parent composite where the selector will be added.
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
* Targets can be null or an empty array, in which case the table is disabled. * Targets can be null or an empty array, in which case the table is disabled.
@@ -79,7 +79,7 @@ public class SdkTargetSelector {
mInnerGroup.setLayout(new GridLayout()); mInnerGroup.setLayout(new GridLayout());
mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
mInnerGroup.setFont(parent.getFont()); mInnerGroup.setFont(parent.getFont());
mAllowSelection = allowSelection; mAllowSelection = allowSelection;
int style = SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION; int style = SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION;
if (allowSelection) { if (allowSelection) {
@@ -137,7 +137,7 @@ public class SdkTargetSelector {
/** /**
* Changes the targets of the SDK Target Selector. * Changes the targets of the SDK Target Selector.
* *
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
*/ */
public void setTargets(IAndroidTarget[] targets) { public void setTargets(IAndroidTarget[] targets) {
@@ -154,19 +154,19 @@ public class SdkTargetSelector {
* The {@link TableItem#getData()} contains an {@link IAndroidTarget}. * The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
* <p/> * <p/>
* It is recommended that the caller uses the {@link #getSelected()} method instead. * It is recommended that the caller uses the {@link #getSelected()} method instead.
* *
* @param selectionListener The new listener or null to remove it. * @param selectionListener The new listener or null to remove it.
*/ */
public void setSelectionListener(SelectionListener selectionListener) { public void setSelectionListener(SelectionListener selectionListener) {
mSelectionListener = selectionListener; mSelectionListener = selectionListener;
} }
/** /**
* Sets the current target selection. * Sets the current target selection.
* <p/> * <p/>
* If the selection is actually changed, this will invoke the selection listener * If the selection is actually changed, this will invoke the selection listener
* (if any) with a null event. * (if any) with a null event.
* *
* @param target the target to be selection * @param target the target to be selection
* @return true if the target could be selected, false otherwise. * @return true if the target could be selected, false otherwise.
*/ */
@@ -174,7 +174,7 @@ public class SdkTargetSelector {
if (!mAllowSelection) { if (!mAllowSelection) {
return false; return false;
} }
boolean found = false; boolean found = false;
boolean modified = false; boolean modified = false;
@@ -192,17 +192,17 @@ public class SdkTargetSelector {
} }
} }
} }
if (modified && mSelectionListener != null) { if (modified && mSelectionListener != null) {
mSelectionListener.widgetSelected(null); mSelectionListener.widgetSelected(null);
} }
return found; return found;
} }
/** /**
* Returns the selected item. * Returns the selected item.
* *
* @return The selected item or null. * @return The selected item or null.
*/ */
public IAndroidTarget getSelected() { public IAndroidTarget getSelected() {
@@ -234,7 +234,7 @@ public class SdkTargetSelector {
@Override @Override
public void controlResized(ControlEvent e) { public void controlResized(ControlEvent e) {
Rectangle r = table.getClientArea(); Rectangle r = table.getClientArea();
column0.setWidth(r.width * 30 / 100); // 30% column0.setWidth(r.width * 30 / 100); // 30%
column1.setWidth(r.width * 45 / 100); // 45% column1.setWidth(r.width * 45 / 100); // 45%
column2.setWidth(r.width * 15 / 100); // 15% column2.setWidth(r.width * 15 / 100); // 15%
column3.setWidth(r.width * 10 / 100); // 10% column3.setWidth(r.width * 10 / 100); // 10%
@@ -267,7 +267,7 @@ public class SdkTargetSelector {
mSelectionListener.widgetDefaultSelected(e); mSelectionListener.widgetDefaultSelected(e);
} }
} }
public void widgetSelected(SelectionEvent e) { public void widgetSelected(SelectionEvent e) {
if (e.item instanceof TableItem) { if (e.item instanceof TableItem) {
TableItem i = (TableItem) e.item; TableItem i = (TableItem) e.item;
@@ -315,7 +315,7 @@ public class SdkTargetSelector {
} }
table.removeAll(); table.removeAll();
if (mTargets != null && mTargets.length > 0) { if (mTargets != null && mTargets.length > 0) {
table.setEnabled(true); table.setEnabled(true);
for (IAndroidTarget target : mTargets) { for (IAndroidTarget target : mTargets) {
@@ -350,36 +350,36 @@ public class SdkTargetSelector {
} }
/* /*
* Reference: * Reference:
* http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
*/ */
final Listener listener = new Listener() { final Listener listener = new Listener() {
public void handleEvent(Event event) { public void handleEvent(Event event) {
switch(event.type) { switch(event.type) {
case SWT.KeyDown: case SWT.KeyDown:
case SWT.MouseExit: case SWT.MouseExit:
case SWT.MouseDown: case SWT.MouseDown:
return; return;
case SWT.MouseHover: case SWT.MouseHover:
updateDescription(table.getItem(new Point(event.x, event.y))); updateDescription(table.getItem(new Point(event.x, event.y)));
break; break;
case SWT.Selection: case SWT.Selection:
if (event.item instanceof TableItem) { if (event.item instanceof TableItem) {
updateDescription((TableItem) event.item); updateDescription((TableItem) event.item);
} }
break; break;
default: default:
return; return;
} }
} }
}; };
table.addListener(SWT.Dispose, listener); table.addListener(SWT.Dispose, listener);
table.addListener(SWT.KeyDown, listener); table.addListener(SWT.KeyDown, listener);
table.addListener(SWT.MouseMove, listener); table.addListener(SWT.MouseMove, listener);
@@ -414,5 +414,5 @@ public class SdkTargetSelector {
enableControl(c2, enabled); enableControl(c2, enabled);
} }
} }
} }

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.internal.repository.IDescription;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
/*
* TODO list
* - check source => toggle packages: all, none
* - check package => set source check to tri-state
* - check callback => install enable if has selection
* - fill columns (or remove them?)
* - select tree item: delete site enable if add-on source
* - select tree item: refresh enable if source
* - load add-on sites from pref
* - delete site callback, update pref
* - refresh callback
* - install selected callback
*/
public class AvailablePackagesPage extends Composite {
private final UpdaterData mUpdaterData;
private CheckboxTreeViewer mTreeViewerSources;
private Tree mTreeSources;
private TreeColumn mColumnAvailSummary;
private TreeColumn mColumnAvailApiLevel;
private TreeColumn mColumnAvailRevision;
private TreeColumn mColumnAvailOs;
private TreeColumn mColumnAvailInstalled;
private Group mDescriptionContainer;
private Button mAddSiteButton;
private Button mRemoveSiteButton;
private Label mPlaceholder3;
private Button mRefreshButton;
private Button mInstallSelectedButton;
private Label mDescriptionLabel;
/**
* Create the composite.
* @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer.
*/
public AvailablePackagesPage(Composite parent, UpdaterData updaterData) {
super(parent, SWT.BORDER);
mUpdaterData = updaterData != null ? updaterData : new UpdaterData();
createContents(this);
}
private void createContents(Composite parent) {
parent.setLayout(new GridLayout(5, false));
mTreeViewerSources = new CheckboxTreeViewer(parent, SWT.BORDER);
mTreeViewerSources.setContentProvider(mUpdaterData.getSources().getContentProvider());
mTreeViewerSources.setLabelProvider(mUpdaterData.getSources().getLabelProvider());
mTreeSources = mTreeViewerSources.getTree();
mTreeSources.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onTreeSelected(); //$hide$
}
});
mTreeSources.setHeaderVisible(true);
mTreeSources.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
mColumnAvailSummary = new TreeColumn(mTreeSources, SWT.NONE);
mColumnAvailSummary.setWidth(289);
mColumnAvailSummary.setText("Summary");
mColumnAvailApiLevel = new TreeColumn(mTreeSources, SWT.NONE);
mColumnAvailApiLevel.setWidth(66);
mColumnAvailApiLevel.setText("API Level");
mColumnAvailRevision = new TreeColumn(mTreeSources, SWT.NONE);
mColumnAvailRevision.setWidth(63);
mColumnAvailRevision.setText("Revision");
mColumnAvailOs = new TreeColumn(mTreeSources, SWT.NONE);
mColumnAvailOs.setWidth(100);
mColumnAvailOs.setText("OS/Arch");
mColumnAvailInstalled = new TreeColumn(mTreeSources, SWT.NONE);
mColumnAvailInstalled.setWidth(59);
mColumnAvailInstalled.setText("Installed");
mDescriptionContainer = new Group(parent, SWT.NONE);
mDescriptionContainer.setLayout(new GridLayout(1, false));
mDescriptionContainer.setText("Description");
mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 5, 1));
mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
mDescriptionLabel.setText("Line1\nLine2\nLine3");
mAddSiteButton = new Button(parent, SWT.NONE);
mAddSiteButton.setText("Add Site...");
mRemoveSiteButton = new Button(parent, SWT.NONE);
mRemoveSiteButton.setText("Delete Site...");
mPlaceholder3 = new Label(parent, SWT.NONE);
mPlaceholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
mRefreshButton = new Button(parent, SWT.NONE);
mRefreshButton.setText("Refresh");
mInstallSelectedButton = new Button(parent, SWT.NONE);
mInstallSelectedButton.setText("Install Selected");
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
// -- Start of internal part ----------
// Hide everything down-below from SWT designer
//$hide>>$
public void setInput(RepoSources sources) {
mTreeViewerSources.setInput(sources);
onTreeSelected();
}
private void onTreeSelected() {
ISelection sel = mTreeViewerSources.getSelection();
if (sel instanceof ITreeSelection) {
Object elem = ((ITreeSelection) sel).getFirstElement();
if (elem instanceof IDescription) {
mDescriptionLabel.setText(((IDescription) elem).getLongDescription());
mDescriptionContainer.layout(true);
return;
}
}
mDescriptionLabel.setText(""); //$NON-NLS1-$
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -1,7 +1,23 @@
package com.android.sdkuilib.repository; /*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
import com.android.sdkuilib.repository.ProgressTask.ThreadTask; package com.android.sdkuilib.internal.repository;
import com.android.sdkuilib.repository.UpdaterWindow.UpdaterData;
import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskMonitor;
import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
@@ -17,6 +33,17 @@ import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
/*
* TODO list
* - parse local repo
* - create entries
* - select => update desc, enable update + delete, enable home page if url
* - home page callback
* - update callback
* - delete callback
* - refresh callback
*/
public class InstalledPackagesPage extends Composite { public class InstalledPackagesPage extends Composite {
private UpdaterData mUpdaterData; private UpdaterData mUpdaterData;
@@ -29,24 +56,25 @@ public class InstalledPackagesPage extends Composite {
private TableColumn mColumnInstSummary; private TableColumn mColumnInstSummary;
private TableColumn mColumnInstApiLevel; private TableColumn mColumnInstApiLevel;
private TableColumn mColumnInstRevision; private TableColumn mColumnInstRevision;
private Group mInstDescription; private Group mDescriptionContainer;
private Composite mInstButtons; private Composite mInstButtons;
private Button mInstUpdate; private Button mInstUpdate;
private Label mPlaceholder1; private Label mPlaceholder1;
private Button mInstDelete; private Button mInstDelete;
private Label mPlaceholder2; private Label mPlaceholder2;
private Button mInstHomePage; private Button mInstHomePage;
private Label mDescriptionLabel;
/** /**
* Create the composite. * Create the composite.
* @param parent The parent of the composite. * @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterWindow.UpdaterData}. If null, a local * @param updaterData An instance of {@link UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer. * one will be allocated just to help with the SWT Designer.
*/ */
public InstalledPackagesPage(Composite parent, UpdaterData updaterData) { public InstalledPackagesPage(Composite parent, UpdaterData updaterData) {
super(parent, SWT.BORDER); super(parent, SWT.BORDER);
mUpdaterData = updaterData != null ? updaterData : new UpdaterWindow.UpdaterData(); mUpdaterData = updaterData != null ? updaterData : new UpdaterData();
createContents(this); createContents(this);
} }
@@ -77,9 +105,14 @@ public class InstalledPackagesPage extends Composite {
mColumnInstRevision.setWidth(100); mColumnInstRevision.setWidth(100);
mColumnInstRevision.setText("Revision"); mColumnInstRevision.setText("Revision");
mInstDescription = new Group(parent, SWT.NONE); mDescriptionContainer = new Group(parent, SWT.NONE);
mInstDescription.setText("Description"); mDescriptionContainer.setLayout(new GridLayout(1, false));
mInstDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1)); mDescriptionContainer.setText("Description");
mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1));
mDescriptionLabel.setText("Line1\nLine2\nLine3");
mInstButtons = new Composite(parent, SWT.NONE); mInstButtons = new Composite(parent, SWT.NONE);
mInstButtons.setLayout(new GridLayout(5, false)); mInstButtons.setLayout(new GridLayout(5, false));
@@ -143,8 +176,8 @@ public class InstalledPackagesPage extends Composite {
//$hide>>$ //$hide>>$
protected void onUpdateInstalledPackage() { protected void onUpdateInstalledPackage() {
ProgressTask.start(getShell(), "Test", new ThreadTask() { ProgressTask.start(getShell(), "Test", new ITask() {
public void PerformTask(ITaskMonitor monitor) { public void run(ITaskMonitor monitor) {
monitor.setDescription("Test"); monitor.setDescription("Test");
monitor.setProgressMax(100); monitor.setProgressMax(100);
int n = 0; int n = 0;
@@ -162,7 +195,6 @@ public class InstalledPackagesPage extends Composite {
}); });
} }
// End of hiding from SWT Designer // End of hiding from SWT Designer
//$hide<<$ //$hide<<$
} }

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.sdkuilib.repository; package com.android.sdkuilib.internal.repository;
import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskMonitor;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionAdapter;
@@ -30,6 +33,13 @@ import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
/*
* TODO:
* - trap window.close and treat it as a cancel request
* - on cancel as been clicked *and* the task finished,, change it to a "close" button
*/
class ProgressTask extends Dialog class ProgressTask extends Dialog
implements ITaskMonitor //$hide$ (hide from SWT designer) implements ITaskMonitor //$hide$ (hide from SWT designer)
{ {
@@ -72,6 +82,9 @@ class ProgressTask extends Dialog
display.sleep(); display.sleep();
} }
} }
mCancelRequested = true;
if (!mDialogShell.isDisposed()) { if (!mDialogShell.isDisposed()) {
mDialogShell.close(); mDialogShell.close();
} }
@@ -119,11 +132,7 @@ class ProgressTask extends Dialog
// Hide everything down-below from SWT designer // Hide everything down-below from SWT designer
//$hide>>$ //$hide>>$
public interface ThreadTask { private ITask mTask;
public abstract void PerformTask(ITaskMonitor monitor);
}
private ThreadTask mTask;
/** /**
* Creates a new {@link ProgressTask} with the given title. * Creates a new {@link ProgressTask} with the given title.
@@ -131,7 +140,7 @@ class ProgressTask extends Dialog
* *
* This blocks till the thread ends. * This blocks till the thread ends.
*/ */
public static ProgressTask start(Shell parent, String title, ThreadTask task) { public static ProgressTask start(Shell parent, String title, ITask task) {
ProgressTask t = new ProgressTask(parent); ProgressTask t = new ProgressTask(parent);
t.setText(title); t.setText(title);
t.setTask(task); t.setTask(task);
@@ -159,14 +168,16 @@ class ProgressTask extends Dialog
*/ */
public void setResult(final String result) { public void setResult(final String result) {
mAutomaticallyCloseOnTaskCompletion = false; mAutomaticallyCloseOnTaskCompletion = false;
mDialogShell.getDisplay().asyncExec(new Runnable() { if (!mDialogShell.isDisposed()) {
public void run() { mDialogShell.getDisplay().asyncExec(new Runnable() {
if (!mResultText.isDisposed()) { public void run() {
mResultText.setVisible(true); if (!mResultText.isDisposed()) {
mResultText.setText(result); mResultText.setVisible(true);
mResultText.setText(result);
}
} }
} });
}); }
} }
/** /**
@@ -176,13 +187,15 @@ class ProgressTask extends Dialog
* @see ProgressBar#setMaximum(int) * @see ProgressBar#setMaximum(int)
*/ */
public void setProgressMax(final int max) { public void setProgressMax(final int max) {
mDialogShell.getDisplay().asyncExec(new Runnable() { if (!mDialogShell.isDisposed()) {
public void run() { mDialogShell.getDisplay().asyncExec(new Runnable() {
if (!mProgressBar.isDisposed()) { public void run() {
mProgressBar.setMaximum(max); if (!mProgressBar.isDisposed()) {
mProgressBar.setMaximum(max);
}
} }
} });
}); }
} }
/** /**
@@ -191,13 +204,15 @@ class ProgressTask extends Dialog
* This method can be invoked from a non-UI thread. * This method can be invoked from a non-UI thread.
*/ */
public void incProgress(final int delta) { public void incProgress(final int delta) {
mDialogShell.getDisplay().asyncExec(new Runnable() { if (!mDialogShell.isDisposed()) {
public void run() { mDialogShell.getDisplay().asyncExec(new Runnable() {
if (!mProgressBar.isDisposed()) { public void run() {
mProgressBar.setSelection(mProgressBar.getSelection() + delta); if (!mProgressBar.isDisposed()) {
mProgressBar.setSelection(mProgressBar.getSelection() + delta);
}
} }
} });
}); }
} }
/** /**
@@ -209,12 +224,12 @@ class ProgressTask extends Dialog
} }
/** Sets the task that will execute in a separate thread. */ /** Sets the task that will execute in a separate thread. */
private void setTask(ThreadTask task) { private void setTask(ITask task) {
mTask = task; mTask = task;
} }
/** /**
* Starts the task from {@link #setTask(ThreadTask)} in a separate thread. * Starts the task from {@link #setTask(ITask)} in a separate thread.
* When the task completes, set {@link #mCloseRequested} to end the dialog loop. * When the task completes, set {@link #mCloseRequested} to end the dialog loop.
*/ */
private void startTask() { private void startTask() {
@@ -222,7 +237,7 @@ class ProgressTask extends Dialog
new Thread(getText()) { new Thread(getText()) {
@Override @Override
public void run() { public void run() {
mTask.PerformTask(ProgressTask.this); mTask.run(ProgressTask.this);
if (mAutomaticallyCloseOnTaskCompletion) { if (mAutomaticallyCloseOnTaskCompletion) {
mCloseRequested = true; mCloseRequested = true;
} }

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskFactory;
import org.eclipse.swt.widgets.Shell;
/**
* An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog
* for each new task.
*/
public class ProgressTaskFactory implements ITaskFactory {
private final Shell mShell;
public ProgressTaskFactory(Shell shell) {
mShell = shell;
}
public void start(String title, ITask task) {
ProgressTask.start(mShell, title, task);
}
}

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.sdkuilib.repository; package com.android.sdkuilib.internal.repository;
import com.android.sdklib.internal.repository.IDescription;
import com.android.sdklib.internal.repository.ITaskFactory;
import com.android.sdklib.internal.repository.RepoSource;
import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProvider;
@@ -22,23 +26,24 @@ import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* A list of sdk-repository sources.
* *
* This implementation is UI dependent.
*/ */
class RepoSources { class RepoSources {
private Shell mShell;
private ArrayList<RepoSource> mSources = new ArrayList<RepoSource>(); private ArrayList<RepoSource> mSources = new ArrayList<RepoSource>();
private ITaskFactory mTaskFactory;
public RepoSources() { public RepoSources() {
} }
public void setShell(Shell shell) { public void setTaskFactory(ITaskFactory taskFactory) {
mShell = shell; mTaskFactory = taskFactory;
} }
public void add(RepoSource source) { public void add(RepoSource source) {
@@ -66,6 +71,9 @@ class RepoSources {
/** Returns the toString of the element. */ /** Returns the toString of the element. */
@Override @Override
public String getText(Object element) { public String getText(Object element) {
if (element instanceof IDescription) {
return ((IDescription) element).getShortDescription();
}
return super.getText(element); return super.getText(element);
} }
} }
@@ -112,7 +120,7 @@ class RepoSources {
ArrayList<String> pkgs = source.getPackages(); ArrayList<String> pkgs = source.getPackages();
if (pkgs == null) { if (pkgs == null) {
source.load(mShell); source.load(mTaskFactory);
pkgs = source.getPackages(); pkgs = source.getPackages();
} }
if (pkgs != null) { if (pkgs != null) {

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
/**
* Data shared between {@link UpdaterWindowImpl} and its pages.
*/
class UpdaterData {
private String mOsSdkRoot;
private boolean mUserCanChangeSdkRoot;
private RepoSources mSources = new RepoSources();
public void setOsSdkRoot(String osSdkRoot) {
mOsSdkRoot = osSdkRoot;
}
public String getOsSdkRoot() {
return mOsSdkRoot;
}
public void setUserCanChangeSdkRoot(boolean userCanChangeSdkRoot) {
mUserCanChangeSdkRoot = userCanChangeSdkRoot;
}
public boolean canUserChangeSdkRoot() {
return mUserCanChangeSdkRoot;
}
public void setSources(RepoSources sources) {
mSources = sources;
}
public RepoSources getSources() {
return mSources;
}
}

View File

@@ -0,0 +1,223 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.internal.repository;
import com.android.sdklib.internal.repository.RepoSource;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import java.io.InputStream;
import java.util.ArrayList;
/**
* This is the private implementation of the UpdateWindow.
*/
public class UpdaterWindowImpl {
private final UpdaterData mUpdaterData = new UpdaterData();
private ArrayList<Composite> mPages = new ArrayList<Composite>();
private boolean mInternalPageChange;
// --- UI members ---
protected Shell mAndroidSdkUpdater;
private SashForm mSashForm;
private List mPageList;
private Composite mPagesRootComposite;
private InstalledPackagesPage mInstalledPackagePage;
private AvailablePackagesPage mAvailablePackagesPage;
private StackLayout mStackLayout;
private Image mIconImage;
public UpdaterWindowImpl(String osSdkRoot, boolean userCanChangeSdkRoot) {
mUpdaterData.setOsSdkRoot(osSdkRoot);
mUpdaterData.setUserCanChangeSdkRoot(userCanChangeSdkRoot);
}
/**
* Open the window.
* @wbp.parser.entryPoint
*/
public void open() {
Display display = Display.getDefault();
createContents();
mAndroidSdkUpdater.open();
mAndroidSdkUpdater.layout();
firstInit(); //$hide$ (hide from SWT designer)
while (!mAndroidSdkUpdater.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
mAndroidSdkUpdater = new Shell();
setWindowImage(mAndroidSdkUpdater);
mAndroidSdkUpdater.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer)
}
});
mAndroidSdkUpdater.setLayout(new FillLayout(SWT.HORIZONTAL));
mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
mAndroidSdkUpdater.setSize(745, 433);
mAndroidSdkUpdater.setText("Android SDK Updater");
mSashForm = new SashForm(mAndroidSdkUpdater, SWT.NONE);
mPageList = new List(mSashForm, SWT.BORDER);
mPageList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onPageListSelected(); //$hide$ (hide from SWT designer)
}
});
mPagesRootComposite = new Composite(mSashForm, SWT.NONE);
mStackLayout = new StackLayout();
mPagesRootComposite.setLayout(mStackLayout);
mInstalledPackagePage = new InstalledPackagesPage(mPagesRootComposite, mUpdaterData);
mAvailablePackagesPage = new AvailablePackagesPage(mPagesRootComposite, mUpdaterData);
mSashForm.setWeights(new int[] {150, 576});
}
// -- Start of internal part ----------
// Hide everything down-below from SWT designer
//$hide>>$
// --- UI Callbacks -----------
private void onAndroidSdkUpdaterDispose() {
if (mIconImage != null) {
mIconImage.dispose();
mIconImage = null;
}
}
private void setWindowImage(Shell androidSdkUpdater) {
InputStream stream = getClass().getResourceAsStream("android_icon_16.png"); //$NON-NLS-1$
if (stream != null) {
try {
ImageData imgData = new ImageData(stream);
mIconImage = new Image(mAndroidSdkUpdater.getDisplay(),
imgData,
imgData.getTransparencyMask());
mAndroidSdkUpdater.setImage(mIconImage);
} catch (SWTException e) {
// ignore
} catch (IllegalArgumentException e) {
// ignore
}
}
}
private Shell getShell() {
return mAndroidSdkUpdater;
}
/**
* Once the UI has been created, initialize the content
*/
private void firstInit() {
addPage(mInstalledPackagePage, "Installed Packages");
addPage(mAvailablePackagesPage, "Available Packages");
displayPage(0);
mPageList.setSelection(0);
setupSources();
scanLocalSdkFolders();
}
// --- page switching ---
private void addPage(Composite page, String title) {
page.setData(title);
mPages.add(page);
mPageList.add(title);
}
private void onPageListSelected() {
if (mInternalPageChange == false) {
int index = mPageList.getSelectionIndex();
if (index >= 0) {
displayPage(index);
}
}
}
private void displayPage(int index) {
Composite page = mPages.get(index);
if (page != null) {
mStackLayout.topControl = page;
mPagesRootComposite.layout(true);
if (!mInternalPageChange) {
mInternalPageChange = true;
mPageList.setSelection(index);
mInternalPageChange = false;
}
}
}
private void setupSources() {
mUpdaterData.getSources().setTaskFactory(new ProgressTaskFactory(getShell()));
mUpdaterData.getSources().add(new RepoSource(
"https://dl.google.com/android/eclipse/repository/index.xml", //$NON-NLS-1$
false /* addonOnly */));
String url = System.getenv("TEMP_SDK_URL"); // TODO STOPSHIP temporary remove before shipping
if (url != null) {
mUpdaterData.getSources().add(new RepoSource(url, false /* addonOnly */));
}
mAvailablePackagesPage.setInput(mUpdaterData.getSources());
}
private void scanLocalSdkFolders() {
// TODO Auto-generated method stub
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -1,116 +0,0 @@
package com.android.sdkuilib.repository;
import com.android.sdkuilib.repository.UpdaterWindow.UpdaterData;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.swt.SWT;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
class AvailablePackagesPage extends Composite {
private final UpdaterData mUpdaterData;
private CheckboxTreeViewer mTreeViewAvailPkg;
private Tree mTreeAvailPkg;
private TreeColumn mColumnAvailSummary;
private TreeColumn mColumnAvailApiLevel;
private TreeColumn mColumnAvailRevision;
private TreeColumn mColumnAvailOs;
private TreeColumn mColumnAvailInstalled;
private Group mAvailDescription;
private Button mAvailAddSite;
private Button mAvailRemoveSite;
private Label mPlaceholder3;
private Button mAvailRefresh;
private Button mAvailInstallSelected;
/**
* Create the composite.
* @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterWindow.UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer.
*/
public AvailablePackagesPage(Composite parent, UpdaterData updaterData) {
super(parent, SWT.BORDER);
mUpdaterData = updaterData != null ? updaterData : new UpdaterWindow.UpdaterData();
createContents(this);
}
private void createContents(Composite parent) {
parent.setLayout(new GridLayout(5, false));
mTreeViewAvailPkg = new CheckboxTreeViewer(parent, SWT.BORDER);
mTreeViewAvailPkg.setContentProvider(mUpdaterData.getSources().getContentProvider());
mTreeViewAvailPkg.setLabelProvider(mUpdaterData.getSources().getLabelProvider());
mTreeAvailPkg = mTreeViewAvailPkg.getTree();
mTreeAvailPkg.setHeaderVisible(true);
mTreeAvailPkg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
mColumnAvailSummary = new TreeColumn(mTreeAvailPkg, SWT.NONE);
mColumnAvailSummary.setWidth(289);
mColumnAvailSummary.setText("Summary");
mColumnAvailApiLevel = new TreeColumn(mTreeAvailPkg, SWT.NONE);
mColumnAvailApiLevel.setWidth(66);
mColumnAvailApiLevel.setText("API Level");
mColumnAvailRevision = new TreeColumn(mTreeAvailPkg, SWT.NONE);
mColumnAvailRevision.setWidth(63);
mColumnAvailRevision.setText("Revision");
mColumnAvailOs = new TreeColumn(mTreeAvailPkg, SWT.NONE);
mColumnAvailOs.setWidth(100);
mColumnAvailOs.setText("OS/Arch");
mColumnAvailInstalled = new TreeColumn(mTreeAvailPkg, SWT.NONE);
mColumnAvailInstalled.setWidth(59);
mColumnAvailInstalled.setText("Installed");
mAvailDescription = new Group(parent, SWT.NONE);
mAvailDescription.setText("Description");
mAvailDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 5, 1));
mAvailAddSite = new Button(parent, SWT.NONE);
mAvailAddSite.setText("Add Site...");
mAvailRemoveSite = new Button(parent, SWT.NONE);
mAvailRemoveSite.setText("Delete Site...");
mPlaceholder3 = new Label(parent, SWT.NONE);
mPlaceholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
mAvailRefresh = new Button(parent, SWT.NONE);
mAvailRefresh.setText("Refresh");
mAvailInstallSelected = new Button(parent, SWT.NONE);
mAvailInstallSelected.setText("Install Selected");
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
// -- Start of internal part ----------
// Hide everything down-below from SWT designer
//$hide>>$
public void setInput(RepoSources sources) {
mTreeViewAvailPkg.setInput(sources);
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2009 The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
* *
* Licensed under the Eclipse Public License, Version 1.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.eclipse.org/org/documents/epl-v10.php * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,230 +16,31 @@
package com.android.sdkuilib.repository; package com.android.sdkuilib.repository;
import org.eclipse.swt.SWT; import com.android.sdkuilib.internal.repository.UpdaterWindowImpl;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import java.io.InputStream;
import java.util.ArrayList;
/**
* Opens an SDK Updater Window.
*
* This is the public interface for using the window.
*/
public class UpdaterWindow { public class UpdaterWindow {
static class UpdaterData { private UpdaterWindowImpl mWindow;
private String mOsSdkRoot;
private boolean mUserCanChangeSdkRoot;
private RepoSources mSources = new RepoSources();
public void setOsSdkRoot(String osSdkRoot) {
mOsSdkRoot = osSdkRoot;
}
public String getOsSdkRoot() {
return mOsSdkRoot;
}
public void setUserCanChangeSdkRoot(boolean userCanChangeSdkRoot) {
mUserCanChangeSdkRoot = userCanChangeSdkRoot;
}
public boolean canUserChangeSdkRoot() {
return mUserCanChangeSdkRoot;
}
public void setSources(RepoSources sources) {
mSources = sources;
}
public RepoSources getSources() {
return mSources;
}
}
private final UpdaterData mUpdaterData = new UpdaterData();
private ArrayList<Composite> mPages = new ArrayList<Composite>();
private boolean mInternalPageChange;
// --- UI members ---
protected Shell mAndroidSdkUpdater;
private SashForm mSashForm;
private List mPageList;
private Composite mPagesRootComposite;
private InstalledPackagesPage mInstalledPackagePage;
private AvailablePackagesPage mAvailablePackagesPage;
private StackLayout mStackLayout;
private Image mIconImage;
/**
* Creates a new window. Caller must call open(), which will block.
* @param osSdkRoot The OS path to the SDK root.
* @param userCanChangeSdkRoot If true, the window lets the user change the SDK path
* being browsed.
*/
public UpdaterWindow(String osSdkRoot, boolean userCanChangeSdkRoot) { public UpdaterWindow(String osSdkRoot, boolean userCanChangeSdkRoot) {
mUpdaterData.setOsSdkRoot(osSdkRoot); mWindow = new UpdaterWindowImpl(osSdkRoot, userCanChangeSdkRoot);
mUpdaterData.setUserCanChangeSdkRoot(userCanChangeSdkRoot);
} }
/** /**
* Open the window. * Opens the window.
* @wbp.parser.entryPoint
*/ */
public void open() { public void open() {
Display display = Display.getDefault(); mWindow.open();
createContents();
mAndroidSdkUpdater.open();
mAndroidSdkUpdater.layout();
firstInit(); //$hide$ (hide from SWT designer)
while (!mAndroidSdkUpdater.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} }
/**
* Create contents of the window.
*/
protected void createContents() {
mAndroidSdkUpdater = new Shell();
setWindowImage(mAndroidSdkUpdater);
mAndroidSdkUpdater.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer)
}
});
mAndroidSdkUpdater.setLayout(new FillLayout(SWT.HORIZONTAL));
mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
mAndroidSdkUpdater.setSize(745, 433);
mAndroidSdkUpdater.setText("Android SDK Updater");
mSashForm = new SashForm(mAndroidSdkUpdater, SWT.NONE);
mPageList = new List(mSashForm, SWT.BORDER);
mPageList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onPageListSelected(e); //$hide$ (hide from SWT designer)
}
});
mPagesRootComposite = new Composite(mSashForm, SWT.NONE);
mStackLayout = new StackLayout();
mPagesRootComposite.setLayout(mStackLayout);
mInstalledPackagePage = new InstalledPackagesPage(mPagesRootComposite, mUpdaterData);
mAvailablePackagesPage = new AvailablePackagesPage(mPagesRootComposite, mUpdaterData);
mSashForm.setWeights(new int[] {150, 576});
}
// -- Start of internal part ----------
// Hide everything down-below from SWT designer
//$hide>>$
// --- UI Callbacks -----------
private void onAndroidSdkUpdaterDispose() {
if (mIconImage != null) {
mIconImage.dispose();
mIconImage = null;
}
}
private void setWindowImage(Shell androidSdkUpdater) {
InputStream stream = getClass().getResourceAsStream("android_icon_16.png"); //$NON-NLS-1$
if (stream != null) {
try {
ImageData imgData = new ImageData(stream);
mIconImage = new Image(mAndroidSdkUpdater.getDisplay(),
imgData,
imgData.getTransparencyMask());
mAndroidSdkUpdater.setImage(mIconImage);
} catch (SWTException e) {
// ignore
} catch (IllegalArgumentException e) {
// ignore
}
}
}
private Shell getShell() {
return mAndroidSdkUpdater;
}
/**
* Once the UI has been created, initialize the content
*/
private void firstInit() {
addPage(mInstalledPackagePage, "Installed Packages");
addPage(mAvailablePackagesPage, "Available Packages");
displayPage(0);
mPageList.setSelection(0);
setupSources();
scanLocalSdkFolders();
}
// --- page switching ---
private void addPage(Composite page, String title) {
page.setData(title);
mPages.add(page);
mPageList.add(title);
}
private void onPageListSelected(SelectionEvent e) {
if (mInternalPageChange == false) {
int index = mPageList.getSelectionIndex();
if (index >= 0) {
displayPage(index);
}
}
}
private void displayPage(int index) {
Composite page = mPages.get(index);
if (page != null) {
mStackLayout.topControl = page;
mPagesRootComposite.layout(true);
if (!mInternalPageChange) {
mInternalPageChange = true;
mPageList.setSelection(index);
mInternalPageChange = false;
}
}
}
private void setupSources() {
mUpdaterData.getSources().setShell(getShell());
mUpdaterData.getSources().add(new RepoSource(
"https://dl.google.com/android/eclipse/repository/index.xml", //$NON-NLS-1$
false /* addonOnly */));
mUpdaterData.getSources().add(new RepoSource(
"http://www.corp.google.com/~raphael/android/sdk-repo/repository.xml", //$NON-NLS-1$
false /* addonOnly */));
mAvailablePackagesPage.setInput(mUpdaterData.getSources());
}
private void scanLocalSdkFolders() {
// TODO Auto-generated method stub
}
// End of hiding from SWT Designer
//$hide<<$
} }