/* * 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.Archive; import com.android.sdklib.internal.repository.IDescription; import com.android.sdklib.internal.repository.Package; import com.android.sdkuilib.repository.ISdkChangeListener; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Rectangle; 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.Table; import org.eclipse.swt.widgets.TableColumn; import java.io.File; public class LocalPackagesPage extends Composite implements ISdkChangeListener { private final UpdaterData mUpdaterData; private Label mSdkLocLabel; private TableViewer mTableViewerPackages; private Table mTablePackages; private TableColumn mColumnPackages; private Group mDescriptionContainer; private Composite mContainerButtons; private Button mUpdateButton; private Label mPlaceholder1; private Button mDeleteButton; private Label mPlaceholder2; private Button mRefreshButton; private Label mDescriptionLabel; /** * Create the composite. * @param parent The parent of the composite. * @param updaterData An instance of {@link UpdaterData}. */ public LocalPackagesPage(Composite parent, UpdaterData updaterData) { super(parent, SWT.BORDER); mUpdaterData = updaterData; createContents(this); postCreate(); //$hide$ } private void createContents(Composite parent) { parent.setLayout(new GridLayout(3, false)); mSdkLocLabel = new Label(parent, SWT.NONE); mSdkLocLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 3, 1)); mSdkLocLabel.setText("SDK Location: " + (mUpdaterData.getOsSdkRoot() != null ? mUpdaterData.getOsSdkRoot() : "<unknown>")); mTableViewerPackages = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION); mTablePackages = mTableViewerPackages.getTable(); mTablePackages.setHeaderVisible(true); mTablePackages.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); mTablePackages.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onTreeSelected(); //$hide$ } }); mColumnPackages = new TableColumn(mTablePackages, SWT.NONE); mColumnPackages.setWidth(377); mColumnPackages.setText("Installed packages"); mDescriptionContainer = new Group(parent, SWT.NONE); mDescriptionContainer.setLayout(new GridLayout(1, false)); 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"); mContainerButtons = new Composite(parent, SWT.NONE); mContainerButtons.setLayout(new GridLayout(5, false)); mContainerButtons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); mUpdateButton = new Button(mContainerButtons, SWT.NONE); mUpdateButton.setText("Update All..."); mUpdateButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onUpdateSelected(); //$hide$ (hide from SWT designer) } }); mPlaceholder1 = new Label(mContainerButtons, SWT.NONE); mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); mDeleteButton = new Button(mContainerButtons, SWT.NONE); mDeleteButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); mDeleteButton.setText("Delete..."); mDeleteButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onDeleteSelected(); //$hide$ (hide from SWT designer) } }); mPlaceholder2 = new Label(mContainerButtons, SWT.NONE); mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); mRefreshButton = new Button(mContainerButtons, SWT.NONE); mRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); mRefreshButton.setText("Refresh"); mRefreshButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onRefreshSelected(); //$hide$ (hide from SWT designer) } }); } @Override public void dispose() { mUpdaterData.removeListener(this); super.dispose(); } @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>>$ /** * Called by the constructor right after {@link #createContents(Composite)}. */ private void postCreate() { mUpdaterData.addListeners(this); adjustColumnsWidth(); updateButtonsState(); } /** * Adds a listener to adjust the columns width when the parent is resized. * <p/> * If we need something more fancy, we might want to use this: * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co */ private void adjustColumnsWidth() { // Add a listener to resize the column to the full width of the table ControlAdapter resizer = new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Rectangle r = mTablePackages.getClientArea(); mColumnPackages.setWidth(r.width); } }; mTablePackages.addControlListener(resizer); resizer.controlResized(null); } /** * Enable or disable buttons depending on list content and selection */ private void updateButtonsState() { ISelection sel = mTableViewerPackages.getSelection(); boolean hasSelection = sel != null && !sel.isEmpty(); mUpdateButton.setEnabled(mTablePackages.getItemCount() > 0); mDeleteButton.setEnabled(hasSelection); mRefreshButton.setEnabled(true); } /** * Called when an item in the package table viewer is selected. * If the items is an {@link IDescription} (as it should), this will display its long * description in the description area. Otherwise when the item is not of the expected * type or there is no selection, it empties the description area. */ private void onTreeSelected() { updateButtonsState(); ISelection sel = mTableViewerPackages.getSelection(); if (sel instanceof IStructuredSelection) { Object elem = ((IStructuredSelection) sel).getFirstElement(); if (elem instanceof IDescription) { mDescriptionLabel.setText(((IDescription) elem).getLongDescription()); mDescriptionContainer.layout(true); return; } } mDescriptionLabel.setText(""); //$NON-NLS1-$ } /** User selected the 'update all' button. */ private void onUpdateSelected() { mUpdaterData.updateOrInstallAll_WithGUI( null /*selectedArchives*/, false /* includeObsoletes */); } private void onDeleteSelected() { ISelection sel = mTableViewerPackages.getSelection(); if (sel instanceof IStructuredSelection) { Object elem = ((IStructuredSelection) sel).getFirstElement(); if (elem instanceof Package) { String title = "Delete SDK Package"; String error = null; Package p = (Package) elem; Archive[] archives = p.getArchives(); if (archives.length == 1 && archives[0] != null && archives[0].isLocal()) { Archive archive = archives[0]; String osPath = archive.getLocalOsPath(); File dir = new File(osPath); if (dir.isDirectory()) { String msg = String.format("Are you sure you want to delete '%1$s' at '%2$s'? This cannot be undone.", p.getShortDescription(), osPath); if (MessageDialog.openQuestion(getShell(), title, msg)) { archive.deleteLocal(); // refresh list onRefreshSelected(); } } else { error = "Directory not found for this package"; } } else { error = "No local archive found for this package"; } if (error != null) { MessageDialog.openError(getShell(), title, error); } return; } } } private void onRefreshSelected() { mUpdaterData.reloadSdk(); updateButtonsState(); } // --- Implementation of ISdkChangeListener --- public void onSdkLoaded() { onSdkReload(); } public void onSdkReload() { LocalSdkAdapter localSdkAdapter = mUpdaterData.getLocalSdkAdapter(); mTableViewerPackages.setLabelProvider( localSdkAdapter.getLabelProvider()); mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider()); mTableViewerPackages.setInput(localSdkAdapter); onTreeSelected(); } public void preInstallHook() { // nothing to be done for now. } public void postInstallHook() { // nothing to be done for now. } // End of hiding from SWT Designer //$hide<<$ }