/* * 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.core; import com.android.sdklib.internal.repository.IDescription; import com.android.sdklib.internal.repository.archives.Archive; import com.android.sdklib.internal.repository.packages.Package; import com.android.sdklib.internal.repository.sources.SdkSource; import com.android.sdkuilib.internal.repository.ui.PackagesPage; import org.eclipse.jface.viewers.IInputProvider; 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 IInputProvider mViewer; private boolean mDisplayArchives; public PkgContentProvider(IInputProvider 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 viewer, Object oldInput, Object newInput) { // 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() { if (mSource.isEnabled()) { return mSource.getLongDescription(); } else { return "Loading from this site has been disabled. " + "To enable it, use Tools > Manage Add-ons Sites."; } } @Override public String getShortDescription() { if (mSource.isEnabled()) { return "No packages found."; } else { return "This site is disabled. "; } } } }