Home | History | Annotate | Download | only in refactoring
      1 /*
      2  * Copyright (C) 2011 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 
     17 package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
     18 
     19 import static com.android.SdkConstants.REQUEST_FOCUS;
     20 import static com.android.SdkConstants.VIEW_FRAGMENT;
     21 import static com.android.SdkConstants.VIEW_INCLUDE;
     22 
     23 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
     24 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
     25 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CustomViewFinder;
     26 import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository;
     27 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
     28 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
     29 import com.android.sdklib.IAndroidTarget;
     30 import com.android.utils.Pair;
     31 
     32 import org.eclipse.core.resources.IProject;
     33 import org.eclipse.swt.SWT;
     34 import org.eclipse.swt.layout.GridData;
     35 import org.eclipse.swt.layout.GridLayout;
     36 import org.eclipse.swt.widgets.Combo;
     37 import org.eclipse.swt.widgets.Composite;
     38 import org.eclipse.swt.widgets.Label;
     39 
     40 import java.util.ArrayList;
     41 import java.util.List;
     42 
     43 class ChangeViewWizard extends VisualRefactoringWizard {
     44     private static final String SEPARATOR_LABEL =
     45         "----------------------------------------"; //$NON-NLS-1$
     46 
     47     public ChangeViewWizard(ChangeViewRefactoring ref, LayoutEditorDelegate editor) {
     48         super(ref, editor);
     49         setDefaultPageTitle("Change Widget Type");
     50     }
     51 
     52     @Override
     53     protected void addUserInputPages() {
     54         ChangeViewRefactoring ref = (ChangeViewRefactoring) getRefactoring();
     55         List<String> oldTypes = ref.getOldTypes();
     56         String oldType = null;
     57         for (String type : oldTypes) {
     58             if (oldType == null) {
     59                 oldType = type;
     60             } else if (!oldType.equals(type)) {
     61                 // If the types differ, don't offer related categories
     62                 oldType = null;
     63                 break;
     64             }
     65         }
     66         addPage(new InputPage(mDelegate.getEditor().getProject(), oldType));
     67     }
     68 
     69     /** Wizard page which inputs parameters for the {@link ChangeViewRefactoring} operation */
     70     private static class InputPage extends VisualRefactoringInputPage {
     71         private final IProject mProject;
     72         private Combo mTypeCombo;
     73         private final String mOldType;
     74         private List<String> mClassNames;
     75 
     76         public InputPage(IProject project, String oldType) {
     77             super("ChangeViewInputPage");  //$NON-NLS-1$
     78             mProject = project;
     79             mOldType = oldType;
     80         }
     81 
     82         @Override
     83         public void createControl(Composite parent) {
     84             Composite composite = new Composite(parent, SWT.NONE);
     85             composite.setLayout(new GridLayout(2, false));
     86 
     87             Label typeLabel = new Label(composite, SWT.NONE);
     88             typeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
     89             typeLabel.setText("New Widget Type:");
     90 
     91             mTypeCombo = new Combo(composite, SWT.READ_ONLY);
     92             mTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
     93             mTypeCombo.addSelectionListener(mSelectionValidateListener);
     94 
     95             mClassNames = getWidgetTypes(mOldType, mTypeCombo);
     96             mTypeCombo.select(0);
     97 
     98             setControl(composite);
     99             validatePage();
    100 
    101             mTypeCombo.setFocus();
    102         }
    103 
    104         private List<String> getWidgetTypes(String oldType, Combo combo) {
    105             List<String> classNames = new ArrayList<String>();
    106 
    107             // Populate type combo
    108             Sdk currentSdk = Sdk.getCurrent();
    109             if (currentSdk != null) {
    110                 IAndroidTarget target = currentSdk.getTarget(mProject);
    111                 if (target != null) {
    112                     // Try to pick "related" widgets to the one you have selected.
    113                     // For example, for an AnalogClock, display DigitalClock first.
    114                     // For a Text, offer EditText, AutoComplete, etc.
    115                     if (oldType != null) {
    116                         ViewMetadataRepository repository = ViewMetadataRepository.get();
    117                         List<String> relatedTo = repository.getRelatedTo(oldType);
    118                         if (relatedTo.size() > 0) {
    119                             for (String className : relatedTo) {
    120                                 String base = className.substring(className.lastIndexOf('.') + 1);
    121                                 combo.add(base);
    122                                 classNames.add(className);
    123                             }
    124                             combo.add(SEPARATOR_LABEL);
    125                             classNames.add(null);
    126                         }
    127                     }
    128 
    129                     Pair<List<String>,List<String>> result =
    130                         CustomViewFinder.findViews(mProject, false);
    131                     List<String> customViews = result.getFirst();
    132                     List<String> thirdPartyViews = result.getSecond();
    133                     if (customViews.size() > 0) {
    134                         for (String view : customViews) {
    135                             combo.add(view);
    136                             classNames.add(view);
    137                         }
    138                         combo.add(SEPARATOR_LABEL);
    139                         classNames.add(null);
    140                     }
    141 
    142                     if (thirdPartyViews.size() > 0) {
    143                         for (String view : thirdPartyViews) {
    144                             combo.add(view);
    145                             classNames.add(view);
    146                         }
    147                         combo.add(SEPARATOR_LABEL);
    148                         classNames.add(null);
    149                     }
    150 
    151                     AndroidTargetData targetData = currentSdk.getTargetData(target);
    152                     if (targetData != null) {
    153                         // Now add ALL known layout descriptors in case the user has
    154                         // a special case
    155                         List<ViewElementDescriptor> descriptors =
    156                             targetData.getLayoutDescriptors().getViewDescriptors();
    157                         for (ViewElementDescriptor d : descriptors) {
    158                             String className = d.getFullClassName();
    159                             if (className.equals(VIEW_INCLUDE)
    160                                     || className.equals(VIEW_FRAGMENT)
    161                                     || className.equals(REQUEST_FOCUS)) {
    162                                 continue;
    163                             }
    164                             combo.add(d.getUiName());
    165                             classNames.add(className);
    166 
    167                         }
    168                     }
    169                 }
    170             } else {
    171                 combo.add("SDK not initialized");
    172                 classNames.add(null);
    173             }
    174 
    175             return classNames;
    176         }
    177 
    178         @Override
    179         protected boolean validatePage() {
    180             boolean ok = true;
    181             int selectionIndex = mTypeCombo.getSelectionIndex();
    182             String type = selectionIndex != -1 ? mClassNames.get(selectionIndex) : null;
    183             if (type == null) {
    184                 setErrorMessage("Select a widget type to convert to");
    185                 ok = false; // The user has chosen a separator
    186             } else {
    187                 setErrorMessage(null);
    188             }
    189 
    190             // Record state
    191             ChangeViewRefactoring refactoring =
    192                 (ChangeViewRefactoring) getRefactoring();
    193             refactoring.setType(type);
    194 
    195             setPageComplete(ok);
    196             return ok;
    197         }
    198     }
    199 }
    200