Home | History | Annotate | Download | only in templates
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
      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 package com.android.ide.eclipse.adt.internal.wizards.templates;
     17 
     18 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.CATEGORY_ACTIVITIES;
     19 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.CATEGORY_OTHER;
     20 import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_LAUNCHER;
     21 import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_PADDING;
     22 import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_WIDTH;
     23 
     24 import com.android.ide.eclipse.adt.AdtPlugin;
     25 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageControl;
     26 import com.google.common.collect.Lists;
     27 import com.google.common.io.Files;
     28 
     29 import org.eclipse.core.runtime.IStatus;
     30 import org.eclipse.core.runtime.Status;
     31 import org.eclipse.jface.dialogs.IMessageProvider;
     32 import org.eclipse.jface.resource.JFaceResources;
     33 import org.eclipse.jface.wizard.WizardPage;
     34 import org.eclipse.swt.SWT;
     35 import org.eclipse.swt.events.SelectionEvent;
     36 import org.eclipse.swt.events.SelectionListener;
     37 import org.eclipse.swt.graphics.Font;
     38 import org.eclipse.swt.graphics.Image;
     39 import org.eclipse.swt.layout.GridData;
     40 import org.eclipse.swt.layout.GridLayout;
     41 import org.eclipse.swt.widgets.Button;
     42 import org.eclipse.swt.widgets.Composite;
     43 import org.eclipse.swt.widgets.Label;
     44 import org.eclipse.swt.widgets.List;
     45 
     46 import java.io.ByteArrayInputStream;
     47 import java.io.File;
     48 import java.io.IOException;
     49 import java.util.ArrayList;
     50 
     51 class ActivityPage extends WizardPage implements SelectionListener {
     52     private final NewProjectWizardState mValues;
     53     private List mList;
     54     private Button mCreateToggle;
     55     private java.util.List<File> mTemplates;
     56 
     57     private boolean mIgnore;
     58     private boolean mShown;
     59     private ImageControl mPreview;
     60     private Image mPreviewImage;
     61     private boolean mDisposePreviewImage;
     62     private Label mHeading;
     63     private Label mDescription;
     64     private boolean mOnlyActivities;
     65     private boolean mAskCreate;
     66     private boolean mLauncherActivitiesOnly;
     67 
     68     /**
     69      * Create the wizard.
     70      */
     71     ActivityPage(NewProjectWizardState values, boolean onlyActivities, boolean askCreate) {
     72         super("activityPage"); //$NON-NLS-1$
     73         mValues = values;
     74         mOnlyActivities = onlyActivities;
     75         mAskCreate = askCreate;
     76 
     77         if (onlyActivities) {
     78             setTitle("Create Activity");
     79         } else {
     80             setTitle("Create Android Object");
     81         }
     82         if (onlyActivities && askCreate) {
     83             setDescription(
     84                     "Select whether to create an activity, and if so, what kind of activity.");
     85         } else {
     86             setDescription("Select which template to use");
     87         }
     88     }
     89 
     90     /** Sets whether the activity page should only offer launcher activities */
     91     void setLauncherActivitiesOnly(boolean launcherActivitiesOnly) {
     92         mLauncherActivitiesOnly = launcherActivitiesOnly;
     93     }
     94 
     95     @Override
     96     public void createControl(Composite parent) {
     97         Composite container = new Composite(parent, SWT.NULL);
     98         setControl(container);
     99     }
    100 
    101     @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused
    102     private void onEnter() {
    103         Composite container = (Composite) getControl();
    104         container.setLayout(new GridLayout(3, false));
    105 
    106         if (mAskCreate) {
    107             mCreateToggle = new Button(container, SWT.CHECK);
    108             mCreateToggle.setSelection(true);
    109             mCreateToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
    110             mCreateToggle.setText("Create Activity");
    111             mCreateToggle.addSelectionListener(this);
    112         }
    113 
    114         mList = new List(container, SWT.BORDER | SWT.V_SCROLL);
    115         mList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    116 
    117 
    118         TemplateManager manager = mValues.template.getManager();
    119         java.util.List<File> templates = manager.getTemplates(CATEGORY_ACTIVITIES);
    120 
    121         if (!mOnlyActivities) {
    122             templates.addAll(manager.getTemplates(CATEGORY_OTHER));
    123         }
    124         java.util.List<String> names = new ArrayList<String>(templates.size());
    125         File current = mValues.activityValues.getTemplateLocation();
    126         mTemplates = Lists.newArrayListWithExpectedSize(templates.size());
    127         int index = -1;
    128         for (int i = 0, n = templates.size(); i < n; i++) {
    129             File template = templates.get(i);
    130             TemplateMetadata metadata = manager.getTemplate(template);
    131             if (metadata == null) {
    132                 continue;
    133             }
    134             if (mLauncherActivitiesOnly) {
    135                 Parameter parameter = metadata.getParameter(IS_LAUNCHER);
    136                 if (parameter == null) {
    137                     continue;
    138                 }
    139             }
    140             mTemplates.add(template);
    141             names.add(metadata.getTitle());
    142             if (template.equals(current)) {
    143                 index = names.size();
    144             }
    145         }
    146         String[] items = names.toArray(new String[names.size()]);
    147         mList.setItems(items);
    148         if (index == -1 && !mTemplates.isEmpty()) {
    149             mValues.activityValues.setTemplateLocation(mTemplates.get(0));
    150             index = 0;
    151         }
    152         if (index >= 0) {
    153             mList.setSelection(index);
    154             mList.addSelectionListener(this);
    155         }
    156 
    157         // Preview
    158         mPreview = new ImageControl(container, SWT.NONE, null);
    159         mPreview.setDisposeImage(false); // Handled manually in this class
    160         GridData gd_mImage = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
    161         gd_mImage.widthHint = PREVIEW_WIDTH + 2 * PREVIEW_PADDING;
    162         mPreview.setLayoutData(gd_mImage);
    163         new Label(container, SWT.NONE);
    164 
    165         mHeading = new Label(container, SWT.NONE);
    166         mHeading.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
    167         new Label(container, SWT.NONE);
    168 
    169         mDescription = new Label(container, SWT.WRAP);
    170         mDescription.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
    171 
    172         Font font = JFaceResources.getFontRegistry().getBold(JFaceResources.BANNER_FONT);
    173         if (font != null) {
    174             mHeading.setFont(font);
    175         }
    176 
    177         updatePreview();
    178     }
    179 
    180     private void updatePreview() {
    181         Image oldImage = mPreviewImage;
    182         boolean dispose = mDisposePreviewImage;
    183         mPreviewImage = null;
    184 
    185         String title = "";
    186         String description = "";
    187         TemplateHandler handler = mValues.activityValues.getTemplateHandler();
    188         TemplateMetadata template = handler.getTemplate();
    189         if (template != null) {
    190             String thumb = template.getThumbnailPath();
    191             if (thumb != null && !thumb.isEmpty()) {
    192                 File file = new File(mValues.activityValues.getTemplateLocation(),
    193                         thumb.replace('/', File.separatorChar));
    194                 if (file != null) {
    195                     try {
    196                         byte[] bytes = Files.toByteArray(file);
    197                         ByteArrayInputStream input = new ByteArrayInputStream(bytes);
    198                         mPreviewImage = new Image(getControl().getDisplay(), input);
    199                         mDisposePreviewImage = true;
    200                         input.close();
    201                     } catch (IOException e) {
    202                         AdtPlugin.log(e, null);
    203                     }
    204                 }
    205             } else {
    206                 // Fallback icon
    207                 mDisposePreviewImage = false;
    208                 mPreviewImage = TemplateMetadata.getDefaultTemplateIcon();
    209             }
    210             title = template.getTitle();
    211             description = template.getDescription();
    212         }
    213 
    214         mHeading.setText(title);
    215         mDescription.setText(description);
    216         mPreview.setImage(mPreviewImage);
    217         mPreview.fitToWidth(PREVIEW_WIDTH);
    218 
    219         if (oldImage != null && dispose) {
    220             oldImage.dispose();
    221         }
    222 
    223         Composite parent = (Composite) getControl();
    224         parent.layout(true, true);
    225         parent.redraw();
    226     }
    227 
    228     @Override
    229     public void dispose() {
    230         super.dispose();
    231 
    232         if (mPreviewImage != null && mDisposePreviewImage) {
    233             mDisposePreviewImage = false;
    234             mPreviewImage.dispose();
    235             mPreviewImage = null;
    236         }
    237     }
    238 
    239     @Override
    240     public void setVisible(boolean visible) {
    241         if (visible && !mShown) {
    242             onEnter();
    243         }
    244 
    245         super.setVisible(visible);
    246 
    247         if (visible) {
    248             mShown = true;
    249             if (mAskCreate) {
    250                 try {
    251                     mIgnore = true;
    252                     mCreateToggle.setSelection(mValues.createActivity);
    253                 } finally {
    254                     mIgnore = false;
    255                 }
    256             }
    257         }
    258 
    259         validatePage();
    260     }
    261 
    262 
    263     private void validatePage() {
    264         IStatus status = null;
    265 
    266         if (mValues.createActivity) {
    267             if (mList.getSelectionCount() < 1) {
    268                 status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
    269                         "Select an activity type");
    270             } else {
    271                 TemplateHandler templateHandler = mValues.activityValues.getTemplateHandler();
    272                 status = templateHandler.validateTemplate(mValues.minSdkLevel,
    273                         mValues.getBuildApi());
    274             }
    275         }
    276 
    277         setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
    278         if (status != null) {
    279             setMessage(status.getMessage(),
    280                     status.getSeverity() == IStatus.ERROR
    281                         ? IMessageProvider.ERROR : IMessageProvider.WARNING);
    282         } else {
    283             setErrorMessage(null);
    284             setMessage(null);
    285         }
    286     }
    287 
    288     @Override
    289     public boolean isPageComplete() {
    290         // Ensure that the Finish button isn't enabled until
    291         // the user has reached and completed this page
    292         if (!mShown && mValues.createActivity) {
    293             return false;
    294         }
    295 
    296         return super.isPageComplete();
    297     }
    298 
    299     // ---- Implements SelectionListener ----
    300 
    301     @Override
    302     public void widgetSelected(SelectionEvent e) {
    303         if (mIgnore) {
    304             return;
    305         }
    306 
    307         Object source = e.getSource();
    308         if (source == mCreateToggle) {
    309             mValues.createActivity = mCreateToggle.getSelection();
    310             mList.setEnabled(mValues.createActivity);
    311         } else if (source == mList) {
    312             int index = mList.getSelectionIndex();
    313             if (index >= 0 && index < mTemplates.size()) {
    314                 File template = mTemplates.get(index);
    315                 mValues.activityValues.setTemplateLocation(template);
    316                 updatePreview();
    317             }
    318         }
    319 
    320         validatePage();
    321     }
    322 
    323     @Override
    324     public void widgetDefaultSelected(SelectionEvent e) {
    325     }
    326 }
    327