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