Home | History | Annotate | Download | only in sdkman1
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.sdkuilib.internal.repository.sdkman1;
     18 
     19 import com.android.sdklib.internal.repository.Archive;
     20 import com.android.sdklib.internal.repository.IDescription;
     21 import com.android.sdklib.internal.repository.Package;
     22 import com.android.sdkuilib.internal.repository.UpdaterData;
     23 import com.android.sdkuilib.internal.repository.UpdaterPage;
     24 import com.android.sdkuilib.repository.ISdkChangeListener;
     25 
     26 import org.eclipse.jface.dialogs.MessageDialog;
     27 import org.eclipse.jface.viewers.ISelection;
     28 import org.eclipse.jface.viewers.IStructuredSelection;
     29 import org.eclipse.jface.viewers.TableViewer;
     30 import org.eclipse.swt.SWT;
     31 import org.eclipse.swt.events.ControlAdapter;
     32 import org.eclipse.swt.events.ControlEvent;
     33 import org.eclipse.swt.events.SelectionAdapter;
     34 import org.eclipse.swt.events.SelectionEvent;
     35 import org.eclipse.swt.graphics.Rectangle;
     36 import org.eclipse.swt.layout.GridData;
     37 import org.eclipse.swt.layout.GridLayout;
     38 import org.eclipse.swt.widgets.Button;
     39 import org.eclipse.swt.widgets.Composite;
     40 import org.eclipse.swt.widgets.Group;
     41 import org.eclipse.swt.widgets.Label;
     42 import org.eclipse.swt.widgets.Table;
     43 import org.eclipse.swt.widgets.TableColumn;
     44 
     45 import java.io.File;
     46 
     47 /**
     48  * Page that displays all locally installed packages from the current SDK.
     49  */
     50 public class LocalPackagesPage extends UpdaterPage implements ISdkChangeListener {
     51 
     52     private final UpdaterData mUpdaterData;
     53 
     54     private Label mSdkLocLabel;
     55     private TableViewer mTableViewerPackages;
     56     private Table mTablePackages;
     57     private TableColumn mColumnPackages;
     58     private Group mDescriptionContainer;
     59     private Composite mContainerButtons;
     60     private Button mUpdateButton;
     61     private Label mPlaceholder1;
     62     private Button mDeleteButton;
     63     private Label mPlaceholder2;
     64     private Button mRefreshButton;
     65     private Label mDescriptionLabel;
     66 
     67 
     68     /**
     69      * Create the composite.
     70      * @param parent The parent of the composite.
     71      * @param updaterData An instance of {@link UpdaterData}.
     72      */
     73     public LocalPackagesPage(Composite parent, int swtStyle, UpdaterData updaterData) {
     74         super(parent, swtStyle);
     75 
     76         mUpdaterData = updaterData;
     77 
     78         createContents(this);
     79         postCreate();  //$hide$
     80     }
     81 
     82     private void createContents(Composite parent) {
     83         parent.setLayout(new GridLayout(3, false));
     84 
     85         mSdkLocLabel = new Label(parent, SWT.NONE);
     86         mSdkLocLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 3, 1));
     87         mSdkLocLabel.setText("SDK Location: " +
     88                 (mUpdaterData.getOsSdkRoot() != null ? mUpdaterData.getOsSdkRoot()
     89                                                      : "<unknown>"));
     90 
     91         mTableViewerPackages = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION);
     92         mTablePackages = mTableViewerPackages.getTable();
     93         mTablePackages.setHeaderVisible(true);
     94         mTablePackages.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
     95         mTablePackages.addSelectionListener(new SelectionAdapter() {
     96             @Override
     97             public void widgetSelected(SelectionEvent e) {
     98                 onTreeSelected(); //$hide$
     99             }
    100         });
    101 
    102         mColumnPackages = new TableColumn(mTablePackages, SWT.NONE);
    103         mColumnPackages.setWidth(377);
    104         mColumnPackages.setText("Installed packages");
    105 
    106         mDescriptionContainer = new Group(parent, SWT.NONE);
    107         mDescriptionContainer.setLayout(new GridLayout(1, false));
    108         mDescriptionContainer.setText("Description");
    109         mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
    110 
    111         mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
    112         mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1));
    113         mDescriptionLabel.setText("Line1\nLine2\nLine3");
    114 
    115         mContainerButtons = new Composite(parent, SWT.NONE);
    116         mContainerButtons.setLayout(new GridLayout(5, false));
    117         mContainerButtons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
    118 
    119         mUpdateButton = new Button(mContainerButtons, SWT.NONE);
    120         mUpdateButton.setText("Update All...");
    121         mUpdateButton.addSelectionListener(new SelectionAdapter() {
    122             @Override
    123             public void widgetSelected(SelectionEvent e) {
    124                 onUpdateSelected();  //$hide$ (hide from SWT designer)
    125             }
    126         });
    127 
    128         mPlaceholder1 = new Label(mContainerButtons, SWT.NONE);
    129         mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
    130 
    131         mDeleteButton = new Button(mContainerButtons, SWT.NONE);
    132         mDeleteButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
    133         mDeleteButton.setText("Delete...");
    134         mDeleteButton.addSelectionListener(new SelectionAdapter() {
    135             @Override
    136             public void widgetSelected(SelectionEvent e) {
    137                 onDeleteSelected();  //$hide$ (hide from SWT designer)
    138             }
    139         });
    140 
    141         mPlaceholder2 = new Label(mContainerButtons, SWT.NONE);
    142         mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
    143 
    144         mRefreshButton = new Button(mContainerButtons, SWT.NONE);
    145         mRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    146         mRefreshButton.setText("Refresh");
    147         mRefreshButton.addSelectionListener(new SelectionAdapter() {
    148             @Override
    149             public void widgetSelected(SelectionEvent e) {
    150                 onRefreshSelected();  //$hide$ (hide from SWT designer)
    151             }
    152         });
    153     }
    154 
    155     @Override
    156     public void dispose() {
    157         mUpdaterData.removeListener(this);
    158         super.dispose();
    159     }
    160 
    161     @Override
    162     protected void checkSubclass() {
    163         // Disable the check that prevents subclassing of SWT components
    164     }
    165 
    166     // -- Start of internal part ----------
    167     // Hide everything down-below from SWT designer
    168     //$hide>>$
    169 
    170     /**
    171      * Called by the constructor right after {@link #createContents(Composite)}.
    172      */
    173     private void postCreate() {
    174         mUpdaterData.addListeners(this);
    175         adjustColumnsWidth();
    176         updateButtonsState();
    177     }
    178 
    179     /**
    180      * Adds a listener to adjust the columns width when the parent is resized.
    181      * <p/>
    182      * If we need something more fancy, we might want to use this:
    183      * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
    184      */
    185     private void adjustColumnsWidth() {
    186         // Add a listener to resize the column to the full width of the table
    187         ControlAdapter resizer = new ControlAdapter() {
    188             @Override
    189             public void controlResized(ControlEvent e) {
    190                 Rectangle r = mTablePackages.getClientArea();
    191                 mColumnPackages.setWidth(r.width);
    192             }
    193         };
    194         mTablePackages.addControlListener(resizer);
    195         resizer.controlResized(null);
    196     }
    197 
    198     /**
    199      * Enable or disable buttons depending on list content and selection
    200      */
    201     private void updateButtonsState() {
    202         ISelection sel = mTableViewerPackages.getSelection();
    203         boolean hasSelection = sel != null && !sel.isEmpty();
    204 
    205         mUpdateButton.setEnabled(mTablePackages.getItemCount() > 0);
    206         mDeleteButton.setEnabled(hasSelection);
    207         mRefreshButton.setEnabled(true);
    208     }
    209 
    210     /**
    211      * Called when an item in the package table viewer is selected.
    212      * If the items is an {@link IDescription} (as it should), this will display its long
    213      * description in the description area. Otherwise when the item is not of the expected
    214      * type or there is no selection, it empties the description area.
    215      */
    216     private void onTreeSelected() {
    217         updateButtonsState();
    218 
    219         ISelection sel = mTableViewerPackages.getSelection();
    220         if (sel instanceof IStructuredSelection) {
    221             Object elem = ((IStructuredSelection) sel).getFirstElement();
    222             if (elem instanceof IDescription) {
    223                 mDescriptionLabel.setText(((IDescription) elem).getLongDescription());
    224                 mDescriptionContainer.layout(true);
    225                 return;
    226             }
    227         }
    228         mDescriptionLabel.setText("");  //$NON-NLS1-$
    229     }
    230 
    231     /** User selected the 'update all' button. */
    232     private void onUpdateSelected() {
    233         mUpdaterData.updateOrInstallAll_WithGUI(
    234                 null /*selectedArchives*/,
    235                 false /* includeObsoletes */,
    236                 0 /* flags */);
    237     }
    238 
    239     private void onDeleteSelected() {
    240         ISelection sel = mTableViewerPackages.getSelection();
    241         if (sel instanceof IStructuredSelection) {
    242             Object elem = ((IStructuredSelection) sel).getFirstElement();
    243             if (elem instanceof Package) {
    244 
    245                 String title = "Delete SDK Package";
    246                 String error = null;
    247 
    248                 Package p = (Package) elem;
    249                 Archive[] archives = p.getArchives();
    250                 if (archives.length == 1 && archives[0] != null && archives[0].isLocal()) {
    251                     Archive archive = archives[0];
    252                     String osPath = archive.getLocalOsPath();
    253 
    254                     File dir = new File(osPath);
    255                     if (dir.isDirectory()) {
    256                         String msg = String.format("Are you sure you want to delete '%1$s' at '%2$s'? This cannot be undone.",
    257                                 p.getShortDescription(), osPath);
    258 
    259                         if (MessageDialog.openQuestion(getShell(), title, msg)) {
    260                             archive.deleteLocal();
    261 
    262                             // refresh list
    263                             onRefreshSelected();
    264                         }
    265                     } else {
    266                         error = "Directory not found for this package";
    267                     }
    268                 } else {
    269                     error = "No local archive found for this package";
    270                 }
    271 
    272                 if (error != null) {
    273                     MessageDialog.openError(getShell(), title, error);
    274                 }
    275 
    276                 return;
    277             }
    278         }
    279     }
    280 
    281     private void onRefreshSelected() {
    282         mUpdaterData.reloadSdk();
    283         updateButtonsState();
    284     }
    285 
    286     // --- Implementation of ISdkChangeListener ---
    287 
    288     public void onSdkLoaded() {
    289         onSdkReload();
    290     }
    291 
    292     public void onSdkReload() {
    293         LocalSdkAdapter localSdkAdapter = mUpdaterData.getLocalSdkAdapter();
    294         mTableViewerPackages.setLabelProvider(  localSdkAdapter.getLabelProvider());
    295         mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());
    296         mTableViewerPackages.setInput(localSdkAdapter);
    297         onTreeSelected();
    298     }
    299 
    300     public void preInstallHook() {
    301         // nothing to be done for now.
    302     }
    303 
    304     public void postInstallHook() {
    305         // nothing to be done for now.
    306     }
    307 
    308     // End of hiding from SWT Designer
    309     //$hide<<$
    310 }
    311