aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager/libs/sdkuilib
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2012-03-28 16:43:24 -0700
committerRaphael Moll <ralf@android.com>2012-04-03 16:00:01 -0700
commit6462650a787c96cbb371d6aca201af3d613aad24 (patch)
treed5df3571837f38332db68f8f5b44c21a8fba50fe /sdkmanager/libs/sdkuilib
parentda3dd4690065f3bb547c8827e4efc6e24af4c61d (diff)
downloadsdk-6462650a787c96cbb371d6aca201af3d613aad24.zip
sdk-6462650a787c96cbb371d6aca201af3d613aad24.tar.gz
sdk-6462650a787c96cbb371d6aca201af3d613aad24.tar.bz2
SDK Manager dialog to enable 3rd party addons.
- Change AddonUser dialog: transform current dialog in 2 pages. One is for user to add custom addon site URLs (like the dialog was doing before, unchanged.) - Other tab is to select which official addon sites should be enabled. - Support enable/disable state for each source. - Display disabled sources as such in the tree when in "per-repository" view. - Persist the enable bit state via local pref file. - Refactor a few inner classes out of PackagesPage. Change-Id: Icc8e392d90550e53f1c76dd7aefb31669219973b
Diffstat (limited to 'sdkmanager/libs/sdkuilib')
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java5
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java24
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png (renamed from sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png)bin626 -> 626 bytes
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png (renamed from sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon16.png)bin245 -> 245 bytes
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png (renamed from sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png)bin879 -> 879 bytes
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java385
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java29
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java238
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgContentProvider.java229
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgTreeColumnViewerLabelProvider.java137
10 files changed, 727 insertions, 320 deletions
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
index 4f39b71..dd51a59 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
@@ -328,7 +328,8 @@ public class UpdaterData implements IUpdaterData {
new SdkRepoSource(baseUrl,
SdkSourceCategory.ANDROID_REPO.getUiName()));
- // Load user sources
+ // Load user sources (this will also notify change listeners but this operation is
+ // done early enough that there shouldn't be any anyway.)
sources.loadUserAddons(getSdkLog());
}
@@ -1063,6 +1064,8 @@ public class UpdaterData implements IUpdaterData {
}
}
+ mSources.notifyChangeListeners();
+
mStateFetchRemoteAddonsList = 1;
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java
index fa2e360..1d58541 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java
@@ -20,6 +20,7 @@ import com.android.sdklib.internal.repository.Archive;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.SdkSource;
import com.android.sdklib.internal.repository.SdkSourceCategory;
+import com.android.sdkuilib.internal.repository.sdkman2.PkgContentProvider;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Image;
@@ -108,17 +109,16 @@ public class ImageFactory {
}
if (object instanceof SdkSourceCategory) {
- return getImageByName("source_cat_icon16.png"); //$NON-NLS-1$
+ return getImageByName("source_cat_icon_16.png"); //$NON-NLS-1$
} else if (object instanceof SdkSource) {
- return getImageByName("source_icon16.png"); //$NON-NLS-1$
-
- // TODO reintroduce this in SDK Manager 2 in repository view
- // } else if (object instanceof RepoSourcesAdapter.RepoSourceError) {
- // return getImageByName("error_icon16.png"); //$NON-NLS-1$
- //
- // } else if (object instanceof RepoSourcesAdapter.RepoSourceEmpty) {
- // return getImageByName("nopkg_icon16.png"); //$NON-NLS-1$
+ return getImageByName("source_icon_16.png"); //$NON-NLS-1$
+
+ } else if (object instanceof PkgContentProvider.RepoSourceError) {
+ return getImageByName("error_icon_16.png"); //$NON-NLS-1$
+
+ } else if (object instanceof PkgContentProvider.RepoSourceNotification) {
+ return getImageByName("nopkg_icon_16.png"); //$NON-NLS-1$
}
if (object instanceof Archive) {
@@ -133,6 +133,12 @@ public class ImageFactory {
return getImageByName((String) object);
}
+
+ if (object != null) {
+ // For debugging
+ // System.out.println("No image for object " + object.getClass().getSimpleName());
+ }
+
return null;
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png
index ccb4d0a..ccb4d0a 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon16.png
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png
Binary files differ
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png
index 13c8bb3..13c8bb3 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon16.png
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png
Binary files differ
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png
index 5eb1ead..5eb1ead 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon16.png
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png
Binary files differ
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
index 28a065a..e02d20e 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
@@ -23,9 +23,14 @@ import com.android.sdklib.internal.repository.SdkSources;
import com.android.sdkuilib.internal.repository.UpdaterBaseDialog;
import com.android.sdkuilib.internal.repository.UpdaterData;
import com.android.sdkuilib.ui.GridDataBuilder;
+import com.android.sdkuilib.ui.GridLayoutBuilder;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
@@ -46,110 +51,246 @@ import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
+import java.util.ArrayList;
import java.util.Arrays;
public class AddonSitesDialog extends UpdaterBaseDialog {
- private Table mTable;
- private TableViewer mTableViewer;
- private Button mButtonNew;
- private Button mButtonDelete;
- private Button mButtonEdit;
- private TableColumn mColumnUrl;
+ private final SdkSources mSources;
+ private Table mUserTable;
+ private TableViewer mUserTableViewer;
+ private CheckboxTableViewer mSitesTableViewer;
+ private Button mUserButtonNew;
+ private Button mUserButtonDelete;
+ private Button mUserButtonEdit;
+ private Runnable mSourcesChangeListener;
/**
* Create the dialog.
*
* @param parent The parent's shell
+ * @wbp.parser.entryPoint
*/
public AddonSitesDialog(Shell parent, UpdaterData updaterData) {
super(parent, updaterData, "Add-on Sites");
+ mSources = updaterData.getSources();
+ assert mSources != null;
}
/**
* Create contents of the dialog.
+ * @wbp.parser.entryPoint
*/
- @SuppressWarnings("unused")
@Override
protected void createContents() {
super.createContents();
Shell shell = getShell();
- shell.setMinimumSize(new Point(450, 300));
- shell.setSize(450, 300);
+ shell.setMinimumSize(new Point(300, 300));
+ shell.setSize(600, 400);
+ TabFolder tabFolder = new TabFolder(shell, SWT.NONE);
+ tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ GridDataBuilder.create(tabFolder).fill().grab().hSpan(2);
+
+ TabItem sitesTabItem = new TabItem(tabFolder, SWT.NONE);
+ sitesTabItem.setText("Official Add-on Sites");
+ createTabOfficialSites(tabFolder, sitesTabItem);
+
+ TabItem userTabItem = new TabItem(tabFolder, SWT.NONE);
+ userTabItem.setText("User Defined Sites");
+ createTabUserSites(tabFolder, userTabItem);
+
+ // placeholder for aligning close button
Label label = new Label(shell, SWT.NONE);
+ GridDataBuilder.create(label).hFill().hGrab();
+
+ createCloseButton();
+ }
+
+ void createTabOfficialSites(TabFolder tabFolder, TabItem sitesTabItem) {
+ Composite root = new Composite(tabFolder, SWT.NONE);
+ sitesTabItem.setControl(root);
+ GridLayoutBuilder.create(root).columns(3);
+
+ Label label = new Label(root, SWT.NONE);
+ GridDataBuilder.create(label).hLeft().vCenter().hSpan(3);
+ label.setText(
+ "This lets select which official 3rd-party sites you want to load.\n" +
+ "\n" +
+ "These sites are managed by non-Android vendors to provide add-ons and extra packages.\n" +
+ "They are by default all enabled. When you disable one, the SDK Manager will not check the site for new packages."
+ );
+
+ mSitesTableViewer = CheckboxTableViewer.newCheckList(root, SWT.BORDER | SWT.FULL_SELECTION);
+ mSitesTableViewer.setContentProvider(new SourcesContentProvider());
+
+ Table sitesTable = mSitesTableViewer.getTable();
+ sitesTable.setToolTipText("Enable 3rd-Party Site");
+ sitesTable.setLinesVisible(true);
+ sitesTable.setHeaderVisible(true);
+ GridDataBuilder.create(sitesTable).fill().grab().hSpan(3);
+
+ TableViewerColumn columnViewer = new TableViewerColumn(mSitesTableViewer, SWT.NONE);
+ TableColumn column = columnViewer.getColumn();
+ column.setResizable(true);
+ column.setWidth(150);
+ column.setText("Name");
+ columnViewer.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof SdkSource) {
+ String name = ((SdkSource) element).getUiName();
+ if (name != null) {
+ return name;
+ }
+ return ((SdkSource) element).getShortDescription();
+ }
+ return super.getText(element);
+ }
+ });
+
+ columnViewer = new TableViewerColumn(mSitesTableViewer, SWT.NONE);
+ column = columnViewer.getColumn();
+ column.setResizable(true);
+ column.setWidth(400);
+ column.setText("URL");
+ columnViewer.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof SdkSource) {
+ return ((SdkSource) element).getUrl();
+ }
+ return super.getText(element);
+ }
+ });
+
+ mSitesTableViewer.addCheckStateListener(new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ on_SitesTableViewer_checkStateChanged(event);
+ }
+ });
+
+ // "enable all" and "disable all" buttons under the table
+ Button selectAll = new Button(root, SWT.NONE);
+ selectAll.setText("Enable All");
+ GridDataBuilder.create(selectAll).hLeft();
+ selectAll.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ on_SitesTableViewer_selectAll();
+ }
+ });
+
+ // placeholder between both buttons
+ label = new Label(root, SWT.NONE);
+ GridDataBuilder.create(label).hFill().hGrab();
+
+ Button deselectAll = new Button(root, SWT.NONE);
+ deselectAll.setText("Disable All");
+ GridDataBuilder.create(deselectAll).hRight();
+ deselectAll.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ on_SitesTableViewer_deselectAll();
+ }
+ });
+ }
+
+ void createTabUserSites(TabFolder tabFolder, TabItem userTabItem) {
+ Composite root = new Composite(tabFolder, SWT.NONE);
+ userTabItem.setControl(root);
+ GridLayoutBuilder.create(root).columns(2);
+
+ Label label = new Label(root, SWT.NONE);
GridDataBuilder.create(label).hLeft().vCenter().hSpan(2);
label.setText(
- "This dialog lets you manage the URLs of external add-on sites to be used.\n" +
+ "This lets you manage a list of user-contributed external add-on sites URLs.\n" +
"\n" +
- "Add-on sites can provide new add-ons or \"user\" packages.\n" +
- "They cannot provide standard Android platforms, docs or samples packages.\n" +
+ "Add-on sites can provide new add-ons and extra packages.\n" +
+ "They cannot provide standard Android platforms, system images or docs.\n" +
"Adding a URL here will not allow you to clone an official Android repository."
);
- mTableViewer = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION);
- mTableViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
+ mUserTableViewer = new TableViewer(root, SWT.BORDER | SWT.FULL_SELECTION);
+ mUserTableViewer.setContentProvider(new SourcesContentProvider());
+
+ mUserTableViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
- on_TableViewer_selectionChanged(event);
+ on_UserTableViewer_selectionChanged(event);
}
});
- mTable = mTableViewer.getTable();
- mTable.setLinesVisible(false);
- mTable.addMouseListener(new MouseAdapter() {
+ mUserTable = mUserTableViewer.getTable();
+ mUserTable.setLinesVisible(true);
+ mUserTable.addMouseListener(new MouseAdapter() {
@Override
- public void mouseUp(MouseEvent e) {
- on_Table_mouseUp(e);
+ public void mouseUp(MouseEvent event) {
+ on_UserTable_mouseUp(event);
}
});
- GridDataBuilder.create(mTable).fill().grab().vSpan(5);
+ GridDataBuilder.create(mUserTable).fill().grab().vSpan(5);
- TableViewerColumn tableViewerColumn = new TableViewerColumn(mTableViewer, SWT.NONE);
- mColumnUrl = tableViewerColumn.getColumn();
- mColumnUrl.setWidth(100);
- mColumnUrl.setText("New Column");
+ TableViewerColumn tableViewerColumn = new TableViewerColumn(mUserTableViewer, SWT.NONE);
+ TableColumn userColumnUrl = tableViewerColumn.getColumn();
+ userColumnUrl.setWidth(100);
- mButtonNew = new Button(shell, SWT.NONE);
- mButtonNew.addSelectionListener(new SelectionAdapter() {
+ // Implementation detail: set the label provider on the table viewer *after* associating
+ // a column. This will set the label provider on the column for us.
+ mUserTableViewer.setLabelProvider(new LabelProvider());
+
+
+ mUserButtonNew = new Button(root, SWT.NONE);
+ mUserButtonNew.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- newOrEdit(false /*isEdit*/);
+ userNewOrEdit(false /*isEdit*/);
}
});
- GridDataBuilder.create(mButtonNew).hFill().vCenter();
- mButtonNew.setText("New...");
+ GridDataBuilder.create(mUserButtonNew).hFill().vCenter();
+ mUserButtonNew.setText("New...");
- mButtonEdit = new Button(shell, SWT.NONE);
- mButtonEdit.addSelectionListener(new SelectionAdapter() {
+ mUserButtonEdit = new Button(root, SWT.NONE);
+ mUserButtonEdit.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- newOrEdit(true /*isEdit*/);
+ userNewOrEdit(true /*isEdit*/);
}
});
- GridDataBuilder.create(mButtonEdit).hFill().vCenter();
- mButtonEdit.setText("Edit...");
+ GridDataBuilder.create(mUserButtonEdit).hFill().vCenter();
+ mUserButtonEdit.setText("Edit...");
- mButtonDelete = new Button(shell, SWT.NONE);
- mButtonDelete.addSelectionListener(new SelectionAdapter() {
+ mUserButtonDelete = new Button(root, SWT.NONE);
+ mUserButtonDelete.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- on_ButtonDelete_widgetSelected(e);
+ on_UserButtonDelete_widgetSelected(e);
}
});
- GridDataBuilder.create(mButtonDelete).hFill().vCenter();
- mButtonDelete.setText("Delete...");
- new Label(shell, SWT.NONE);
+ GridDataBuilder.create(mUserButtonDelete).hFill().vCenter();
+ mUserButtonDelete.setText("Delete...");
- createCloseButton();
+ adjustColumnsWidth(mUserTable, userColumnUrl);
+ }
- adjustColumnsWidth(mTable, mColumnUrl);
+ @Override
+ protected void close() {
+ if (mSources != null && mSourcesChangeListener != null) {
+ mSources.removeChangeListener(mSourcesChangeListener);
+ }
+ super.close();
}
/**
@@ -166,12 +307,11 @@ public class AddonSitesDialog extends UpdaterBaseDialog {
});
}
- private void newOrEdit(final boolean isEdit) {
- SdkSources sources = getUpdaterData().getSources();
- final SdkSource[] knownSources = sources.getAllSources();
+ private void userNewOrEdit(final boolean isEdit) {
+ final SdkSource[] knownSources = mSources.getAllSources();
String title = isEdit ? "Edit Add-on Site URL" : "Add Add-on Site URL";
String msg = "Please enter the URL of the addon.xml:";
- IStructuredSelection sel = (IStructuredSelection) mTableViewer.getSelection();
+ IStructuredSelection sel = (IStructuredSelection) mUserTableViewer.getSelection();
final String initialValue = !isEdit || sel.isEmpty() ? null :
sel.getFirstElement().toString();
@@ -228,9 +368,9 @@ public class AddonSitesDialog extends UpdaterBaseDialog {
if (isEdit && initialValue != null) {
// Remove the old value before we add the new one, which is we just
// asserted will be different.
- for (SdkSource source : sources.getSources(SdkSourceCategory.USER_ADDONS)) {
+ for (SdkSource source : mSources.getSources(SdkSourceCategory.USER_ADDONS)) {
if (initialValue.equals(source.getUrl())) {
- sources.remove(source);
+ mSources.remove(source);
break;
}
}
@@ -239,21 +379,22 @@ public class AddonSitesDialog extends UpdaterBaseDialog {
// create the source, store it and update the list
SdkAddonSource newSource = new SdkAddonSource(url, null/*uiName*/);
- sources.add(
+ mSources.add(
SdkSourceCategory.USER_ADDONS,
newSource);
setReturnValue(true);
- loadList();
+ // notify sources change listeners. This will invoke our own loadUserUrlsList().
+ mSources.notifyChangeListeners();
// select the new source
IStructuredSelection newSel = new StructuredSelection(newSource);
- mTableViewer.setSelection(newSel, true /*reveal*/);
+ mUserTableViewer.setSelection(newSel, true /*reveal*/);
}
}
}
- private void on_ButtonDelete_widgetSelected(SelectionEvent e) {
- IStructuredSelection sel = (IStructuredSelection) mTableViewer.getSelection();
+ private void on_UserButtonDelete_widgetSelected(SelectionEvent e) {
+ IStructuredSelection sel = (IStructuredSelection) mUserTableViewer.getSelection();
String selectedUrl = sel.isEmpty() ? null : sel.getFirstElement().toString();
if (selectedUrl == null) {
@@ -265,60 +406,138 @@ public class AddonSitesDialog extends UpdaterBaseDialog {
mb.setText("Delete add-on site");
mb.setMessage(String.format("Do you want to delete the URL %1$s?", selectedUrl));
if (mb.open() == SWT.YES) {
- SdkSources sources = getUpdaterData().getSources();
- for (SdkSource source : sources.getSources(SdkSourceCategory.USER_ADDONS)) {
+ for (SdkSource source : mSources.getSources(SdkSourceCategory.USER_ADDONS)) {
if (selectedUrl.equals(source.getUrl())) {
- sources.remove(source);
+ mSources.remove(source);
setReturnValue(true);
- loadList();
+ mSources.notifyChangeListeners();
+ break;
}
}
}
}
- private void on_Table_mouseUp(MouseEvent e) {
- Point p = new Point(e.x, e.y);
- if (mTable.getItem(p) == null) {
- mTable.deselectAll();
- on_TableViewer_selectionChanged(null /*event*/);
+ private void on_UserTable_mouseUp(MouseEvent event) {
+ Point p = new Point(event.x, event.y);
+ if (mUserTable.getItem(p) == null) {
+ mUserTable.deselectAll();
+ on_UserTableViewer_selectionChanged(null /*event*/);
+ }
+ }
+
+ private void on_UserTableViewer_selectionChanged(SelectionChangedEvent event) {
+ ISelection sel = mUserTableViewer.getSelection();
+ mUserButtonDelete.setEnabled(!sel.isEmpty());
+ mUserButtonEdit.setEnabled(!sel.isEmpty());
+ }
+
+ private void on_SitesTableViewer_checkStateChanged(CheckStateChangedEvent event) {
+ Object element = event.getElement();
+ if (element instanceof SdkSource) {
+ SdkSource source = (SdkSource) element;
+ boolean isChecked = event.getChecked();
+ if (source.isEnabled() != isChecked) {
+ setReturnValue(true);
+ source.setEnabled(isChecked);
+ mSources.notifyChangeListeners();
+ }
+ }
+ }
+
+ private void on_SitesTableViewer_selectAll() {
+ for (Object item : (Object[]) mSitesTableViewer.getInput()) {
+ if (!mSitesTableViewer.getChecked(item)) {
+ mSitesTableViewer.setChecked(item, true);
+ on_SitesTableViewer_checkStateChanged(
+ new CheckStateChangedEvent(mSitesTableViewer, item, true));
+ }
}
}
- private void on_TableViewer_selectionChanged(SelectionChangedEvent event) {
- ISelection sel = mTableViewer.getSelection();
- mButtonDelete.setEnabled(!sel.isEmpty());
- mButtonEdit.setEnabled(!sel.isEmpty());
+ private void on_SitesTableViewer_deselectAll() {
+ for (Object item : (Object[]) mSitesTableViewer.getInput()) {
+ if (mSitesTableViewer.getChecked(item)) {
+ mSitesTableViewer.setChecked(item, false);
+ on_SitesTableViewer_checkStateChanged(
+ new CheckStateChangedEvent(mSitesTableViewer, item, false));
+ }
+ }
}
+
@Override
protected void postCreate() {
+ // A runnable to initially load and then update the user urls & sites lists.
+ final Runnable updateInUiThread = new Runnable() {
+ @Override
+ public void run() {
+ loadUserUrlsList();
+ loadSiteUrlsList();
+ }
+ };
+
+ // A listener that runs when the sources have changed.
+ // This is most likely called on a worker thread.
+ mSourcesChangeListener = new Runnable() {
+ @Override
+ public void run() {
+ Shell shell = getShell();
+ if (shell != null) {
+ Display display = shell.getDisplay();
+ if (display != null) {
+ display.syncExec(updateInUiThread);
+ }
+ }
+ }
+ };
+
+ mSources.addChangeListener(mSourcesChangeListener);
+
// initialize the list
- mTableViewer.setLabelProvider(new LabelProvider());
- mTableViewer.setContentProvider(new SourcesContentProvider());
- loadList();
+ updateInUiThread.run();
}
- private void loadList() {
- if (getUpdaterData() != null) {
- SdkSource[] knownSources =
- getUpdaterData().getSources().getSources(SdkSourceCategory.USER_ADDONS);
- Arrays.sort(knownSources);
+ private void loadUserUrlsList() {
+ SdkSource[] knownSources = mSources.getSources(SdkSourceCategory.USER_ADDONS);
+ Arrays.sort(knownSources);
- ISelection oldSelection = mTableViewer.getSelection();
+ ISelection oldSelection = mUserTableViewer.getSelection();
- mTableViewer.setInput(knownSources);
- mTableViewer.refresh();
- // initialize buttons' state that depend on the list
- on_TableViewer_selectionChanged(null /*event*/);
+ mUserTableViewer.setInput(knownSources);
+ mUserTableViewer.refresh();
+ // initialize buttons' state that depend on the list
+ on_UserTableViewer_selectionChanged(null /*event*/);
- if (oldSelection != null && !oldSelection.isEmpty()) {
- mTableViewer.setSelection(oldSelection, true /*reveal*/);
+ if (oldSelection != null && !oldSelection.isEmpty()) {
+ mUserTableViewer.setSelection(oldSelection, true /*reveal*/);
+ }
+ }
+
+ private void loadSiteUrlsList() {
+ SdkSource[] knownSources = mSources.getSources(SdkSourceCategory.ADDONS_3RD_PARTY);
+ Arrays.sort(knownSources);
+
+ ISelection oldSelection = mSitesTableViewer.getSelection();
+
+ mSitesTableViewer.setInput(knownSources);
+ mSitesTableViewer.refresh();
+
+ if (oldSelection != null && !oldSelection.isEmpty()) {
+ mSitesTableViewer.setSelection(oldSelection, true /*reveal*/);
+ }
+
+ // Check the sources which are currently enabled.
+ ArrayList<SdkSource> disabled = new ArrayList<SdkSource>(knownSources.length);
+ for (SdkSource source : knownSources) {
+ if (source.isEnabled()) {
+ disabled.add(source);
}
}
+ mSitesTableViewer.setCheckedElements(disabled.toArray());
}
- private static class SourcesContentProvider implements IStructuredContentProvider {
+ private static class SourcesContentProvider implements IStructuredContentProvider {
@Override
public void dispose() {
// pass
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
index 3d7cdb0..0774905 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
@@ -302,9 +302,7 @@ class PackagesDiffLogic {
}
public boolean updateSourcePackages(SdkSource source, Package[] newPackages) {
- if (newPackages.length > 0) {
- mVisitedSources.add(source);
- }
+ mVisitedSources.add(source);
if (source == null) {
return processLocals(this, newPackages);
} else {
@@ -759,6 +757,31 @@ class PackagesDiffLogic {
* {@link UpdateOp} describing the Sort-by-Source operation.
*/
private class UpdateOpSource extends UpdateOp {
+
+ @Override
+ public boolean updateSourcePackages(SdkSource source, Package[] newPackages) {
+ // When displaying the repo by source, we want to create all the
+ // categories so that they can appear on the UI even if empty.
+ if (source != null) {
+ List<PkgCategory> cats = getCategories();
+ Object catKey = source;
+ PkgCategory cat = findCurrentCategory(cats, catKey);
+
+ if (cat == null) {
+ // This is a new category. Create it and add it to the list.
+ cat = createCategory(catKey);
+ synchronized (cats) {
+ cats.add(cat);
+ }
+ sortCategoryList();
+ }
+
+ keep(cat);
+ }
+
+ return super.updateSourcePackages(source, newPackages);
+ }
+
@Override
public Object getCategoryKey(Package pkg) {
// Sort by source
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
index d6eb73e..99801b0 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
@@ -36,7 +36,6 @@ import com.android.sdkuilib.ui.GridDataBuilder;
import com.android.sdkuilib.ui.GridLayoutBuilder;
import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
@@ -48,8 +47,6 @@ import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITableFontProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
-import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
@@ -59,7 +56,6 @@ 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.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
@@ -424,6 +420,8 @@ public class PackagesPage extends UpdaterPage
case TOGGLE_SHOW_ARCHIVES:
mDisplayArchives = !mDisplayArchives;
// Force the viewer to be refreshed
+ ((PkgContentProvider) mTreeViewer.getContentProvider()).setDisplayArchives(
+ mDisplayArchives);
mTreeViewer.setInput(null);
refreshViewerInput();
syncViewerSelection();
@@ -523,7 +521,6 @@ public class PackagesPage extends UpdaterPage
item.setSelection(value);
}
}
-
}
private void postCreate() {
@@ -531,13 +528,19 @@ public class PackagesPage extends UpdaterPage
mTextSdkOsPath.setText(mUpdaterData.getOsSdkRoot());
}
- mTreeViewer.setContentProvider(new PkgContentProvider());
+ mTreeViewer.setContentProvider(new PkgContentProvider(mTreeViewer));
+ ((PkgContentProvider) mTreeViewer.getContentProvider()).setDisplayArchives(
+ mDisplayArchives);
ColumnViewerToolTipSupport.enableFor(mTreeViewer, ToolTip.NO_RECREATE);
- mColumnApi.setLabelProvider (new PkgTreeColumnViewerLabelProvider(mColumnApi));
- mColumnName.setLabelProvider (new PkgTreeColumnViewerLabelProvider(mColumnName));
- mColumnStatus.setLabelProvider (new PkgTreeColumnViewerLabelProvider(mColumnStatus));
- mColumnRevision.setLabelProvider(new PkgTreeColumnViewerLabelProvider(mColumnRevision));
+ mColumnApi.setLabelProvider(
+ new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mColumnApi)));
+ mColumnName.setLabelProvider(
+ new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mColumnName)));
+ mColumnStatus.setLabelProvider(
+ new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mColumnStatus)));
+ mColumnRevision.setLabelProvider(
+ new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mColumnRevision)));
FontData fontData = mTree.getFont().getFontData()[0];
fontData.setStyle(SWT.ITALIC);
@@ -1277,116 +1280,6 @@ public class PackagesPage extends UpdaterPage
// ----------------------
- /**
- * A custom version of {@link TreeColumnViewerLabelProvider} which
- * handles {@link TreePath}s and delegates content to a base
- * {@link PkgCellLabelProvider} for the given {@link TreeViewerColumn}.
- * <p/>
- * The implementation handles a variety of providers (table label, table
- * color, table font) but does not implement a tooltip provider, so we
- * delegate the calls here to the appropriate {@link PkgCellLabelProvider}.
- * <p/>
- * Only {@link #getToolTipText(Object)} is really useful for us but we
- * delegate all the tooltip calls for completeness and avoid surprises later
- * if we ever decide to override more things in the label provider.
- */
- public class PkgTreeColumnViewerLabelProvider extends TreeColumnViewerLabelProvider {
-
- private CellLabelProvider mTooltipProvider;
-
- public PkgTreeColumnViewerLabelProvider(TreeViewerColumn column) {
- super(new PkgCellLabelProvider(column));
- }
-
- @Override
- public void setProviders(Object provider) {
- super.setProviders(provider);
- if (provider instanceof CellLabelProvider) {
- mTooltipProvider = (CellLabelProvider) provider;
- }
- }
-
- @Override
- public Image getToolTipImage(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipImage(object);
- }
- return super.getToolTipImage(object);
- }
-
- @Override
- public String getToolTipText(Object element) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipText(element);
- }
- return super.getToolTipText(element);
- }
-
- @Override
- public Color getToolTipBackgroundColor(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipBackgroundColor(object);
- }
- return super.getToolTipBackgroundColor(object);
- }
-
- @Override
- public Color getToolTipForegroundColor(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipForegroundColor(object);
- }
- return super.getToolTipForegroundColor(object);
- }
-
- @Override
- public Font getToolTipFont(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipFont(object);
- }
- return super.getToolTipFont(object);
- }
-
- @Override
- public Point getToolTipShift(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipShift(object);
- }
- return super.getToolTipShift(object);
- }
-
- @Override
- public boolean useNativeToolTip(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.useNativeToolTip(object);
- }
- return super.useNativeToolTip(object);
- }
-
- @Override
- public int getToolTipTimeDisplayed(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipTimeDisplayed(object);
- }
- return super.getToolTipTimeDisplayed(object);
- }
-
- @Override
- public int getToolTipDisplayDelayTime(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipDisplayDelayTime(object);
- }
- return super.getToolTipDisplayDelayTime(object);
- }
-
- @Override
- public int getToolTipStyle(Object object) {
- if (mTooltipProvider != null) {
- return mTooltipProvider.getToolTipStyle(object);
- }
- return super.getToolTipStyle(object);
- }
- }
-
public class PkgCellLabelProvider extends ColumnLabelProvider implements ITableFontProvider {
private final TreeViewerColumn mColumn;
@@ -1400,7 +1293,6 @@ public class PackagesPage extends UpdaterPage
public String getText(Object element) {
if (mColumn == mColumnName) {
-
if (element instanceof PkgCategory) {
return ((PkgCategory) element).getLabel();
} else if (element instanceof PkgItem) {
@@ -1410,7 +1302,6 @@ public class PackagesPage extends UpdaterPage
}
} else if (mColumn == mColumnApi) {
-
int api = -1;
if (element instanceof PkgItem) {
api = ((PkgItem) element).getApi();
@@ -1420,14 +1311,12 @@ public class PackagesPage extends UpdaterPage
}
} else if (mColumn == mColumnRevision) {
-
if (element instanceof PkgItem) {
PkgItem pkg = (PkgItem) element;
return Integer.toString(pkg.getRevision());
}
} else if (mColumn == mColumnStatus) {
-
if (element instanceof PkgItem) {
PkgItem pkg = (PkgItem) element;
@@ -1458,7 +1347,7 @@ public class PackagesPage extends UpdaterPage
}
}
- return "";
+ return ""; //$NON-NLS-1$
}
private String getPkgItemName(PkgItem item) {
@@ -1622,105 +1511,6 @@ public class PackagesPage extends UpdaterPage
}
}
- private class PkgContentProvider implements ITreeContentProvider {
-
- @Override
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof ArrayList<?>) {
- return ((ArrayList<?>) parentElement).toArray();
-
- } else if (parentElement instanceof PkgCategory) {
- return ((PkgCategory) parentElement).getItems().toArray();
-
- } else if (parentElement instanceof PkgItem) {
- if (mDisplayArchives) {
-
- Package pkg = ((PkgItem) parentElement).getUpdatePkg();
-
- // Display update packages as sub-items if the details mode is activated.
- if (pkg != null) {
- return new Object[] { pkg };
- }
-
- return ((PkgItem) parentElement).getArchives();
- }
-
- } else if (parentElement instanceof Package) {
- if (mDisplayArchives) {
- return ((Package) parentElement).getArchives();
- }
-
- }
-
- return new Object[0];
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object getParent(Object element) {
- // This operation is expensive, so we do the minimum
- // and don't try to cover all cases.
-
- if (element instanceof PkgItem) {
- Object input = mTreeViewer.getInput();
- if (input != null) {
- for (PkgCategory cat : (List<PkgCategory>) input) {
- if (cat.getItems().contains(element)) {
- return cat;
- }
- }
- }
- }
-
- return null;
- }
-
- @Override
- public boolean hasChildren(Object parentElement) {
- if (parentElement instanceof ArrayList<?>) {
- return true;
-
- } else if (parentElement instanceof PkgCategory) {
- return true;
-
- } else if (parentElement instanceof PkgItem) {
- if (mDisplayArchives) {
- Package pkg = ((PkgItem) parentElement).getUpdatePkg();
-
- // Display update packages as sub-items if the details mode is activated.
- if (pkg != null) {
- return true;
- }
-
- Archive[] archives = ((PkgItem) parentElement).getArchives();
- return archives.length > 0;
- }
- } else if (parentElement instanceof Package) {
- if (mDisplayArchives) {
- return ((Package) parentElement).getArchives().length > 0;
- }
- }
-
- return false;
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return getChildren(inputElement);
- }
-
- @Override
- public void dispose() {
- // unused
-
- }
-
- @Override
- public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
- // unused
- }
- }
-
// --- Implementation of ISdkChangeListener ---
@Override
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgContentProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgContentProvider.java
new file mode 100755
index 0000000..bd3bd0e
--- /dev/null
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgContentProvider.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2012 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.sdkman2;
+
+import com.android.sdklib.internal.repository.Archive;
+import com.android.sdklib.internal.repository.IDescription;
+import com.android.sdklib.internal.repository.Package;
+import com.android.sdklib.internal.repository.SdkSource;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Content provider for the main tree view in {@link PackagesPage}.
+ */
+public class PkgContentProvider implements ITreeContentProvider {
+
+ private final Viewer mViewer;
+ private boolean mDisplayArchives;
+
+ public PkgContentProvider(Viewer viewer) {
+ mViewer = viewer;
+ }
+
+ public void setDisplayArchives(boolean displayArchives) {
+ mDisplayArchives = displayArchives;
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof ArrayList<?>) {
+ return ((ArrayList<?>) parentElement).toArray();
+
+ } else if (parentElement instanceof PkgCategorySource) {
+ return getSourceChildren((PkgCategorySource) parentElement);
+
+ } else if (parentElement instanceof PkgCategory) {
+ return ((PkgCategory) parentElement).getItems().toArray();
+
+ } else if (parentElement instanceof PkgItem) {
+ if (mDisplayArchives) {
+
+ Package pkg = ((PkgItem) parentElement).getUpdatePkg();
+
+ // Display update packages as sub-items if the details mode is activated.
+ if (pkg != null) {
+ return new Object[] { pkg };
+ }
+
+ return ((PkgItem) parentElement).getArchives();
+ }
+
+ } else if (parentElement instanceof Package) {
+ if (mDisplayArchives) {
+ return ((Package) parentElement).getArchives();
+ }
+
+ }
+
+ return new Object[0];
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object getParent(Object element) {
+ // This operation is expensive, so we do the minimum
+ // and don't try to cover all cases.
+
+ if (element instanceof PkgItem) {
+ Object input = mViewer.getInput();
+ if (input != null) {
+ for (PkgCategory cat : (List<PkgCategory>) input) {
+ if (cat.getItems().contains(element)) {
+ return cat;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object parentElement) {
+ if (parentElement instanceof ArrayList<?>) {
+ return true;
+
+ } else if (parentElement instanceof PkgCategory) {
+ return true;
+
+ } else if (parentElement instanceof PkgItem) {
+ if (mDisplayArchives) {
+ Package pkg = ((PkgItem) parentElement).getUpdatePkg();
+
+ // Display update packages as sub-items if the details mode is activated.
+ if (pkg != null) {
+ return true;
+ }
+
+ Archive[] archives = ((PkgItem) parentElement).getArchives();
+ return archives.length > 0;
+ }
+ } else if (parentElement instanceof Package) {
+ if (mDisplayArchives) {
+ return ((Package) parentElement).getArchives().length > 0;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ @Override
+ public void dispose() {
+ // unused
+
+ }
+
+ @Override
+ public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
+ // unused
+ }
+
+
+ private Object[] getSourceChildren(PkgCategorySource parentElement) {
+ List<?> children = parentElement.getItems();
+
+ SdkSource source = parentElement.getSource();
+ IDescription error = null;
+ IDescription empty = null;
+
+ String errStr = source.getFetchError();
+ if (errStr != null) {
+ error = new RepoSourceError(source);
+ }
+ if (!source.isEnabled() || children.isEmpty()) {
+ empty = new RepoSourceNotification(source);
+ }
+
+ if (error != null || empty != null) {
+ ArrayList<Object> children2 = new ArrayList<Object>();
+ if (error != null) {
+ children2.add(error);
+ }
+ if (empty != null) {
+ children2.add(empty);
+ }
+ children2.addAll(children);
+ children = children2;
+ }
+
+ return children.toArray();
+ }
+
+
+ /**
+ * A dummy entry returned for sources which had load errors.
+ * It displays a summary of the error as its short description or
+ * it displays the source's long description.
+ */
+ public static class RepoSourceError implements IDescription {
+
+ private final SdkSource mSource;
+
+ public RepoSourceError(SdkSource source) {
+ mSource = source;
+ }
+
+ @Override
+ public String getLongDescription() {
+ return mSource.getLongDescription();
+ }
+
+ @Override
+ public String getShortDescription() {
+ return mSource.getFetchError();
+ }
+ }
+
+ /**
+ * A dummy entry returned for sources with no packages.
+ * We need that to force the SWT tree to display an open/close triangle
+ * even for empty sources.
+ */
+ public static class RepoSourceNotification implements IDescription {
+
+ private final SdkSource mSource;
+
+ public RepoSourceNotification(SdkSource source) {
+ mSource = source;
+ }
+
+ @Override
+ public String getLongDescription() {
+ return mSource.getLongDescription();
+ }
+
+ @Override
+ public String getShortDescription() {
+ if (mSource.isEnabled()) {
+ return "No packages found.";
+ } else {
+ return "This site is disabled.";
+ }
+ }
+ }
+
+}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgTreeColumnViewerLabelProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgTreeColumnViewerLabelProvider.java
new file mode 100755
index 0000000..392c87e
--- /dev/null
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgTreeColumnViewerLabelProvider.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2012 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.sdkman2;
+
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * A custom version of {@link TreeColumnViewerLabelProvider} which
+ * handles {@link TreePath}s and delegates content to the given
+ * {@link ColumnLabelProvider} for a given {@link TreeViewerColumn}.
+ * <p/>
+ * The implementation handles a variety of providers (table label, table
+ * color, table font) but does not implement a tooltip provider, so we
+ * delegate the calls here to the appropriate {@link ColumnLabelProvider}.
+ * <p/>
+ * Only {@link #getToolTipText(Object)} is really useful for us but we
+ * delegate all the tooltip calls for completeness and avoid surprises later
+ * if we ever decide to override more things in the label provider.
+ */
+class PkgTreeColumnViewerLabelProvider extends TreeColumnViewerLabelProvider {
+
+ private CellLabelProvider mTooltipProvider;
+
+ public PkgTreeColumnViewerLabelProvider(ColumnLabelProvider columnLabelProvider) {
+ super(columnLabelProvider);
+ }
+
+ @Override
+ public void setProviders(Object provider) {
+ super.setProviders(provider);
+ if (provider instanceof CellLabelProvider) {
+ mTooltipProvider = (CellLabelProvider) provider;
+ }
+ }
+
+ @Override
+ public Image getToolTipImage(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipImage(object);
+ }
+ return super.getToolTipImage(object);
+ }
+
+ @Override
+ public String getToolTipText(Object element) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipText(element);
+ }
+ return super.getToolTipText(element);
+ }
+
+ @Override
+ public Color getToolTipBackgroundColor(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipBackgroundColor(object);
+ }
+ return super.getToolTipBackgroundColor(object);
+ }
+
+ @Override
+ public Color getToolTipForegroundColor(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipForegroundColor(object);
+ }
+ return super.getToolTipForegroundColor(object);
+ }
+
+ @Override
+ public Font getToolTipFont(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipFont(object);
+ }
+ return super.getToolTipFont(object);
+ }
+
+ @Override
+ public Point getToolTipShift(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipShift(object);
+ }
+ return super.getToolTipShift(object);
+ }
+
+ @Override
+ public boolean useNativeToolTip(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.useNativeToolTip(object);
+ }
+ return super.useNativeToolTip(object);
+ }
+
+ @Override
+ public int getToolTipTimeDisplayed(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipTimeDisplayed(object);
+ }
+ return super.getToolTipTimeDisplayed(object);
+ }
+
+ @Override
+ public int getToolTipDisplayDelayTime(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipDisplayDelayTime(object);
+ }
+ return super.getToolTipDisplayDelayTime(object);
+ }
+
+ @Override
+ public int getToolTipStyle(Object object) {
+ if (mTooltipProvider != null) {
+ return mTooltipProvider.getToolTipStyle(object);
+ }
+ return super.getToolTipStyle(object);
+ }
+}