From 8585e68b4072583e84bac8ade8d8f74718e719c3 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 11 Aug 2009 14:26:29 -0700 Subject: [PATCH] BUG 2039245 : Need to show something in the source if there are no available package Also moves the "Show updates only" checkbox around. --- .../repository/RemotePackagesPage.java | 23 ++- .../repository/RepoSourcesAdapter.java | 142 +++++++++++++----- .../repository/icons/ImageFactory.java | 21 +-- .../repository/icons/nopkg_icon16.png | Bin 0 -> 397 bytes 4 files changed, 123 insertions(+), 63 deletions(-) create mode 100755 tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java index a7c1a83a1..6ea040c34 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java @@ -62,7 +62,6 @@ public class RemotePackagesPage extends Composite implements ISdkListener { private Group mDescriptionContainer; private Button mAddSiteButton; private Button mDeleteSiteButton; - private Label mPlaceholder3; private Button mRefreshButton; private Button mInstallSelectedButton; private Label mDescriptionLabel; @@ -118,16 +117,6 @@ public class RemotePackagesPage extends Composite implements ISdkListener { spacer.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); gd.heightHint = 0; - mUpdateOnlyCheckBox = new Button(composite, SWT.CHECK); - mUpdateOnlyCheckBox.setText("Display updates only"); - mUpdateOnlyCheckBox.setSelection(mUpdaterData.getSettingsController().getShowUpdateOnly()); - mUpdateOnlyCheckBox.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onShowUpdateOnly(); //$hide$ - } - }); - mDescriptionContainer = new Group(parent, SWT.NONE); mDescriptionContainer.setLayout(new GridLayout(1, false)); mDescriptionContainer.setText("Description"); @@ -155,8 +144,16 @@ public class RemotePackagesPage extends Composite implements ISdkListener { }); mDeleteSiteButton.setText("Delete Site..."); - mPlaceholder3 = new Label(parent, SWT.NONE); - mPlaceholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1)); + mUpdateOnlyCheckBox = new Button(parent, SWT.CHECK); + mUpdateOnlyCheckBox.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1)); + mUpdateOnlyCheckBox.setText("Display updates only"); + mUpdateOnlyCheckBox.setSelection(mUpdaterData.getSettingsController().getShowUpdateOnly()); + mUpdateOnlyCheckBox.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + onShowUpdateOnly(); //$hide$ + } + }); mRefreshButton = new Button(parent, SWT.NONE); mRefreshButton.addSelectionListener(new SelectionAdapter() { diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java index dbf46f593..de12666e2 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java @@ -43,6 +43,11 @@ public class RepoSourcesAdapter { private final UpdaterData mUpdaterData; + /** + * A dummy RepoSource 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 RepoSource mSource; @@ -60,6 +65,33 @@ public class RepoSourcesAdapter { } } + /** + * A dummy RepoSource 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 RepoSourceEmpty implements IDescription { + + private final RepoSource mSource; + private final boolean mEmptyBecauseOfUpdateOnly; + + public RepoSourceEmpty(RepoSource source, boolean emptyBecauseOfUpdateOnly) { + mSource = source; + mEmptyBecauseOfUpdateOnly = emptyBecauseOfUpdateOnly; + } + + public String getLongDescription() { + return mSource.getLongDescription(); + } + + public String getShortDescription() { + if (mEmptyBecauseOfUpdateOnly) { + return "Some packages were found but are not compatible updates."; + } else { + return "No packages found"; + } + } + } public RepoSourcesAdapter(UpdaterData updaterData) { mUpdaterData = updaterData; @@ -137,50 +169,78 @@ public class RepoSourcesAdapter { return mUpdaterData.getSources().getSources(); } else if (parentElement instanceof RepoSource) { - final RepoSource source = (RepoSource) parentElement; - Package[] packages = source.getPackages(); - - if (packages == null && source.getFetchError() == null) { - final boolean forceHttp = mUpdaterData.getSettingsController().getForceHttp(); - - mUpdaterData.getTaskFactory().start("Loading Source", new ITask() { - public void run(ITaskMonitor monitor) { - source.load(monitor, forceHttp); - } - }); - - packages = source.getPackages(); - } - if (packages != null) { - // filter out only the packages that are new/upgrade. - if (mUpdaterData.getSettingsController().getShowUpdateOnly()) { - return filteredPackages(packages); - } - return packages; - } else if (source.getFetchError() != null) { - // Return a dummy entry to display the fetch error - return new Object[] { new RepoSourceError(source) }; - } + return getRepoSourceChildren((RepoSource) parentElement); } else if (parentElement instanceof Package) { - Archive[] archives = ((Package) parentElement).getArchives(); - if (mUpdaterData.getSettingsController().getShowUpdateOnly()) { - for (Archive archive : archives) { - // if we only want the compatible archives, then we just take the first - // one. it's unlikely there are 2 compatible archives for the same - // package - if (archive.isCompatible()) { - return new Object[] { archive }; - } - } - } - - return archives; + return getPackageChildren((Package) parentElement); } return new Object[0]; } + /** + * Returns the list of packages for this repo source, eventually filtered to display + * only update packages. If the list is empty, returns a specific empty node. If there's + * an error, returns a specific error node. + */ + private Object[] getRepoSourceChildren(final RepoSource source) { + Package[] packages = source.getPackages(); + + if (packages == null && source.getFetchError() == null) { + final boolean forceHttp = mUpdaterData.getSettingsController().getForceHttp(); + + mUpdaterData.getTaskFactory().start("Loading Source", new ITask() { + public void run(ITaskMonitor monitor) { + source.load(monitor, forceHttp); + } + }); + + packages = source.getPackages(); + } + + boolean wasEmptyBeforeFilter = (packages == null || packages.length == 0); + + // filter out only the packages that are new/upgrade. + if (packages != null && mUpdaterData.getSettingsController().getShowUpdateOnly()) { + packages = filteredPackages(packages); + } + if (packages != null && packages.length == 0) { + packages = null; + } + + if (packages != null && source.getFetchError() != null) { + // Return a dummy entry to display the fetch error + return new Object[] { new RepoSourceError(source) }; + } + + // Either return a non-null package list or create a new empty node + if (packages != null) { + return packages; + } else { + return new Object[] { new RepoSourceEmpty(source, !wasEmptyBeforeFilter) } ; + } + } + + /** + * Returns the list of archives for the given package, eventually filtering it + * to only show the compatible archives. + */ + private Object[] getPackageChildren(Package pkg) { + Archive[] archives = pkg.getArchives(); + if (mUpdaterData.getSettingsController().getShowUpdateOnly()) { + for (Archive archive : archives) { + // if we only want the compatible archives, then we just take the first + // one. it's unlikely there are 2 compatible archives for the same + // package + if (archive.isCompatible()) { + return new Object[] { archive }; + } + } + } + + return archives; + } + /** * Returns the parent of a given element. * The input {@link RepoSourcesAdapter} is the parent of all {@link RepoSource} elements. @@ -213,7 +273,7 @@ public class RepoSourcesAdapter { * @param remotePackages the list of packages to filter. * @return a non null (but maybe empty) list of new or update packages. */ - private Object[] filteredPackages(Package[] remotePackages) { + private Package[] filteredPackages(Package[] remotePackages) { // get the installed packages Package[] installedPackages = mUpdaterData.getInstalledPackage(); @@ -233,10 +293,10 @@ public class RepoSourcesAdapter { if (info == UpdateInfo.UPDATE) { filteredList.add(remotePkg); newPkg = false; - break; // there shouldn't be 2 revision of the same package + break; // there shouldn't be 2 revisions of the same package } else if (info != UpdateInfo.INCOMPATIBLE) { newPkg = false; - break; // there shouldn't be 2 revision of the same package + break; // there shouldn't be 2 revisions of the same package } } @@ -247,6 +307,6 @@ public class RepoSourcesAdapter { } } - return filteredList.toArray(); + return filteredList.toArray(new Package[filteredList.size()]); } } diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java index bd39c5e82..cbd846e42 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java @@ -91,31 +91,34 @@ public class ImageFactory { */ public Image getImageForObject(Object object) { if (object instanceof RepoSource) { - return getImageByName("source_icon16.png"); + return getImageByName("source_icon16.png"); //$NON-NLS-1$ } else if (object instanceof RepoSourcesAdapter.RepoSourceError) { - return getImageByName("error_icon16.png"); + return getImageByName("error_icon16.png"); //$NON-NLS-1$ + + } else if (object instanceof RepoSourcesAdapter.RepoSourceEmpty) { + return getImageByName("nopkg_icon16.png"); //$NON-NLS-1$ } else if (object instanceof PlatformPackage) { - return getImageByName("android_icon_16.png"); + return getImageByName("android_icon_16.png"); //$NON-NLS-1$ } else if (object instanceof AddonPackage) { - return getImageByName("addon_icon16.png"); + return getImageByName("addon_icon16.png"); //$NON-NLS-1$ } else if (object instanceof ToolPackage) { - return getImageByName("tool_icon16.png"); + return getImageByName("tool_icon16.png"); //$NON-NLS-1$ } else if (object instanceof DocPackage) { - return getImageByName("doc_icon16.png"); + return getImageByName("doc_icon16.png"); //$NON-NLS-1$ } else if (object instanceof ExtraPackage) { - return getImageByName("extra_icon16.png"); + return getImageByName("extra_icon16.png"); //$NON-NLS-1$ } else if (object instanceof Archive) { if (((Archive) object).isCompatible()) { - return getImageByName("archive_icon16.png"); + return getImageByName("archive_icon16.png"); //$NON-NLS-1$ } else { - return getImageByName("incompat_icon16.png"); + return getImageByName("incompat_icon16.png"); //$NON-NLS-1$ } } return null; diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon16.png new file mode 100755 index 0000000000000000000000000000000000000000..147837fd64f0fa22c37cce6f79ce9a8c0d512355 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgga4sKCl6Bnib)<9EuJzX3_EKXmY zZ0ODGDA2m!vR@-Td%n?B7RM&v4V>G;o}G`psTO*{?ah%x-L4+0D}&gMoO+XY?(><5 zHBNfdSryIvEZ_XD_?#9NGBsB#>GZGY11|z!omcjB?th=BBKu{j9Lt-xm%N3dHm?k6 zs;m-Ndo|;z;ohtJ*0fv9?o#7CV!fe$0h57b_byfm=C^(CSs59=U3H$roV@o#E}y%4 zYM}swLA{`^-F`(jsk5sj6!=)vbVOL6SU!<|sGCy))aNFsGd*t3^Lr