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.ide.common.layout.LayoutConstants.FQCN_GRID_LAYOUT;
     20 import static com.android.ide.common.layout.LayoutConstants.FQCN_RELATIVE_LAYOUT;
     21 import static com.android.ide.common.layout.LayoutConstants.GRID_LAYOUT;
     22 import static com.android.ide.common.layout.LayoutConstants.RELATIVE_LAYOUT;
     23 import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_FRAGMENT;
     24 import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_INCLUDE;
     25 import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_MERGE;
     26 
     27 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
     28 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
     29 import com.android.ide.eclipse.adt.internal.editors.layout.gre.PaletteMetadataDescriptor;
     30 import com.android.util.Pair;
     31 
     32 import org.eclipse.core.resources.IProject;
     33 import org.eclipse.swt.SWT;
     34 import org.eclipse.swt.events.SelectionAdapter;
     35 import org.eclipse.swt.events.SelectionEvent;
     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.Combo;
     40 import org.eclipse.swt.widgets.Composite;
     41 import org.eclipse.swt.widgets.Label;
     42 
     43 import java.util.HashSet;
     44 import java.util.List;
     45 import java.util.Set;
     46 
     47 class ChangeLayoutWizard extends VisualRefactoringWizard {
     48 
     49     public ChangeLayoutWizard(ChangeLayoutRefactoring ref, LayoutEditorDelegate editor) {
     50         super(ref, editor);
     51         setDefaultPageTitle("Change Layout");
     52     }
     53 
     54     @Override
     55     protected void addUserInputPages() {
     56         ChangeLayoutRefactoring ref = (ChangeLayoutRefactoring) getRefactoring();
     57         String oldType = ref.getOldType();
     58         addPage(new InputPage(mDelegate.getEditor().getProject(), oldType));
     59     }
     60 
     61     /** Wizard page which inputs parameters for the {@link ChangeLayoutRefactoring} operation */
     62     private static class InputPage extends VisualRefactoringInputPage {
     63         private final IProject mProject;
     64         private final String mOldType;
     65         private Combo mTypeCombo;
     66         private Button mFlatten;
     67         private List<Pair<String, ViewElementDescriptor>> mClassNames;
     68 
     69         public InputPage(IProject project, String oldType) {
     70             super("ChangeLayoutInputPage");  //$NON-NLS-1$
     71             mProject = project;
     72             mOldType = oldType;
     73         }
     74 
     75         @Override
     76         public void createControl(Composite parent) {
     77             Composite composite = new Composite(parent, SWT.NONE);
     78             composite.setLayout(new GridLayout(2, false));
     79 
     80             Label fromLabel = new Label(composite, SWT.NONE);
     81             fromLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
     82             String oldTypeBase = mOldType.substring(mOldType.lastIndexOf('.') + 1);
     83             fromLabel.setText(String.format("Change from %1$s", oldTypeBase));
     84 
     85             Label typeLabel = new Label(composite, SWT.NONE);
     86             typeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
     87             typeLabel.setText("New Layout Type:");
     88 
     89             mTypeCombo = new Combo(composite, SWT.READ_ONLY);
     90             mTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
     91             SelectionAdapter selectionListener = new SelectionAdapter() {
     92                 @Override
     93                 public void widgetSelected(SelectionEvent e) {
     94                     validatePage();
     95                     // Hierarchy flattening only works for relative layout (and any future
     96                     // layouts that can also support arbitrary layouts).
     97                     String text = mTypeCombo.getText();
     98                     mFlatten.setVisible(text.equals(RELATIVE_LAYOUT) || text.equals(GRID_LAYOUT));
     99                 }
    100             };
    101             mTypeCombo.addSelectionListener(selectionListener);
    102             mTypeCombo.addSelectionListener(mSelectionValidateListener);
    103 
    104             mFlatten = new Button(composite, SWT.CHECK);
    105             mFlatten.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER,
    106                     false, false, 2, 1));
    107             mFlatten.setText("Flatten hierarchy");
    108             mFlatten.addSelectionListener(selectionListener);
    109             // Should flattening be selected by default?
    110             mFlatten.setSelection(true);
    111             mFlatten.addSelectionListener(mSelectionValidateListener);
    112 
    113             // We don't exclude RelativeLayout even if the current layout is RelativeLayout,
    114             // in case you are trying to flatten the hierarchy for a hierarchy that has a
    115             // RelativeLayout at the root.
    116             Set<String> exclude = new HashSet<String>();
    117             exclude.add(VIEW_INCLUDE);
    118             exclude.add(VIEW_MERGE);
    119             exclude.add(VIEW_FRAGMENT);
    120             boolean oldIsRelativeLayout = mOldType.equals(FQCN_RELATIVE_LAYOUT);
    121             boolean oldIsGridLayout = mOldType.equals(FQCN_GRID_LAYOUT);
    122             if (oldIsRelativeLayout || oldIsGridLayout) {
    123                 exclude.add(mOldType);
    124             }
    125             mClassNames = WrapInWizard.addLayouts(mProject, mOldType, mTypeCombo, exclude, false);
    126 
    127             boolean gridLayoutAvailable = false;
    128             for (int i = 0; i < mTypeCombo.getItemCount(); i++) {
    129                 if (mTypeCombo.getItem(i).equals(GRID_LAYOUT)) {
    130                     gridLayoutAvailable = true;
    131                     break;
    132                 }
    133             }
    134 
    135             mTypeCombo.select(0);
    136             // The default should be GridLayout (if available) and if not RelativeLayout,
    137             // if available (and not the old Type)
    138             if (gridLayoutAvailable && !oldIsGridLayout) {
    139                 for (int i = 0; i < mTypeCombo.getItemCount(); i++) {
    140                     if (mTypeCombo.getItem(i).equals(GRID_LAYOUT)) {
    141                         mTypeCombo.select(i);
    142                         break;
    143                     }
    144                 }
    145             } else if (!oldIsRelativeLayout) {
    146                 for (int i = 0; i < mTypeCombo.getItemCount(); i++) {
    147                     if (mTypeCombo.getItem(i).equals(RELATIVE_LAYOUT)) {
    148                         mTypeCombo.select(i);
    149                         break;
    150                     }
    151                 }
    152             }
    153             mFlatten.setVisible(mTypeCombo.getText().equals(RELATIVE_LAYOUT)
    154                     || mTypeCombo.getText().equals(GRID_LAYOUT));
    155 
    156             setControl(composite);
    157             validatePage();
    158         }
    159 
    160         @Override
    161         protected boolean validatePage() {
    162             boolean ok = true;
    163 
    164             int selectionIndex = mTypeCombo.getSelectionIndex();
    165             String type = selectionIndex != -1 ? mClassNames.get(selectionIndex).getFirst() : null;
    166             if (type == null) {
    167                 setErrorMessage("Select a layout type");
    168                 ok = false; // The user has chosen a separator
    169             } else {
    170                 setErrorMessage(null);
    171 
    172                 // Record state
    173                 ChangeLayoutRefactoring refactoring =
    174                     (ChangeLayoutRefactoring) getRefactoring();
    175                 refactoring.setType(type);
    176                 refactoring.setFlatten(mFlatten.getSelection());
    177 
    178                 ViewElementDescriptor descriptor = mClassNames.get(selectionIndex).getSecond();
    179                 if (descriptor instanceof PaletteMetadataDescriptor) {
    180                     PaletteMetadataDescriptor paletteDescriptor =
    181                         (PaletteMetadataDescriptor) descriptor;
    182                     String initializedAttributes = paletteDescriptor.getInitializedAttributes();
    183                     if (initializedAttributes != null && initializedAttributes.length() > 0) {
    184                         refactoring.setInitializedAttributes(initializedAttributes);
    185                     }
    186                 } else {
    187                     refactoring.setInitializedAttributes(null);
    188                 }
    189             }
    190 
    191             setPageComplete(ok);
    192             return ok;
    193         }
    194     }
    195 }
    196