diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates')
32 files changed, 0 insertions, 7796 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java deleted file mode 100644 index ba4aedc8a..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.CATEGORY_ACTIVITIES; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.CATEGORY_OTHER; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_LAUNCHER; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_PADDING; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_WIDTH; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageControl; -import com.google.common.collect.Lists; -import com.google.common.io.Files; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.List; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -class ActivityPage extends WizardPage implements SelectionListener { - private final NewProjectWizardState mValues; - private List mList; - private Button mCreateToggle; - private java.util.List<File> mTemplates; - - private boolean mIgnore; - private boolean mShown; - private ImageControl mPreview; - private Image mPreviewImage; - private boolean mDisposePreviewImage; - private Label mHeading; - private Label mDescription; - private boolean mOnlyActivities; - private boolean mAskCreate; - private boolean mLauncherActivitiesOnly; - - /** - * Create the wizard. - */ - ActivityPage(NewProjectWizardState values, boolean onlyActivities, boolean askCreate) { - super("activityPage"); //$NON-NLS-1$ - mValues = values; - mOnlyActivities = onlyActivities; - mAskCreate = askCreate; - - if (onlyActivities) { - setTitle("Create Activity"); - } else { - setTitle("Create Android Object"); - } - if (onlyActivities && askCreate) { - setDescription( - "Select whether to create an activity, and if so, what kind of activity."); - } else { - setDescription("Select which template to use"); - } - } - - /** Sets whether the activity page should only offer launcher activities */ - void setLauncherActivitiesOnly(boolean launcherActivitiesOnly) { - mLauncherActivitiesOnly = launcherActivitiesOnly; - } - - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - } - - @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused - private void onEnter() { - Composite container = (Composite) getControl(); - container.setLayout(new GridLayout(3, false)); - - if (mAskCreate) { - mCreateToggle = new Button(container, SWT.CHECK); - mCreateToggle.setSelection(true); - mCreateToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); - mCreateToggle.setText("Create Activity"); - mCreateToggle.addSelectionListener(this); - } - - mList = new List(container, SWT.BORDER | SWT.V_SCROLL); - mList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - - - TemplateManager manager = mValues.template.getManager(); - java.util.List<File> templates = manager.getTemplates(CATEGORY_ACTIVITIES); - - if (!mOnlyActivities) { - templates.addAll(manager.getTemplates(CATEGORY_OTHER)); - } - java.util.List<String> names = new ArrayList<String>(templates.size()); - File current = mValues.activityValues.getTemplateLocation(); - mTemplates = Lists.newArrayListWithExpectedSize(templates.size()); - int index = -1; - for (int i = 0, n = templates.size(); i < n; i++) { - File template = templates.get(i); - TemplateMetadata metadata = manager.getTemplate(template); - if (metadata == null) { - continue; - } - if (mLauncherActivitiesOnly) { - Parameter parameter = metadata.getParameter(IS_LAUNCHER); - if (parameter == null) { - continue; - } - } - mTemplates.add(template); - names.add(metadata.getTitle()); - if (template.equals(current)) { - index = names.size(); - } - } - String[] items = names.toArray(new String[names.size()]); - mList.setItems(items); - if (index == -1 && !mTemplates.isEmpty()) { - mValues.activityValues.setTemplateLocation(mTemplates.get(0)); - index = 0; - } - if (index >= 0) { - mList.setSelection(index); - mList.addSelectionListener(this); - } - - // Preview - mPreview = new ImageControl(container, SWT.NONE, null); - mPreview.setDisposeImage(false); // Handled manually in this class - GridData gd_mImage = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1); - gd_mImage.widthHint = PREVIEW_WIDTH + 2 * PREVIEW_PADDING; - mPreview.setLayoutData(gd_mImage); - new Label(container, SWT.NONE); - - mHeading = new Label(container, SWT.NONE); - mHeading.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); - new Label(container, SWT.NONE); - - mDescription = new Label(container, SWT.WRAP); - mDescription.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1)); - - Font font = JFaceResources.getFontRegistry().getBold(JFaceResources.BANNER_FONT); - if (font != null) { - mHeading.setFont(font); - } - - updatePreview(); - } - - private void updatePreview() { - Image oldImage = mPreviewImage; - boolean dispose = mDisposePreviewImage; - mPreviewImage = null; - - String title = ""; - String description = ""; - TemplateHandler handler = mValues.activityValues.getTemplateHandler(); - TemplateMetadata template = handler.getTemplate(); - if (template != null) { - String thumb = template.getThumbnailPath(); - if (thumb != null && !thumb.isEmpty()) { - File file = new File(mValues.activityValues.getTemplateLocation(), - thumb.replace('/', File.separatorChar)); - if (file != null) { - try { - byte[] bytes = Files.toByteArray(file); - ByteArrayInputStream input = new ByteArrayInputStream(bytes); - mPreviewImage = new Image(getControl().getDisplay(), input); - mDisposePreviewImage = true; - input.close(); - } catch (IOException e) { - AdtPlugin.log(e, null); - } - } - } else { - // Fallback icon - mDisposePreviewImage = false; - mPreviewImage = TemplateMetadata.getDefaultTemplateIcon(); - } - title = template.getTitle(); - description = template.getDescription(); - } - - mHeading.setText(title); - mDescription.setText(description); - mPreview.setImage(mPreviewImage); - mPreview.fitToWidth(PREVIEW_WIDTH); - - if (oldImage != null && dispose) { - oldImage.dispose(); - } - - Composite parent = (Composite) getControl(); - parent.layout(true, true); - parent.redraw(); - } - - @Override - public void dispose() { - super.dispose(); - - if (mPreviewImage != null && mDisposePreviewImage) { - mDisposePreviewImage = false; - mPreviewImage.dispose(); - mPreviewImage = null; - } - } - - @Override - public void setVisible(boolean visible) { - if (visible && !mShown) { - onEnter(); - } - - super.setVisible(visible); - - if (visible) { - mShown = true; - if (mAskCreate) { - try { - mIgnore = true; - mCreateToggle.setSelection(mValues.createActivity); - } finally { - mIgnore = false; - } - } - } - - validatePage(); - } - - - private void validatePage() { - IStatus status = null; - - if (mValues.createActivity) { - if (mList.getSelectionCount() < 1) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Select an activity type"); - } else { - TemplateHandler templateHandler = mValues.activityValues.getTemplateHandler(); - status = templateHandler.validateTemplate(mValues.minSdkLevel, - mValues.getBuildApi()); - } - } - - setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); - if (status != null) { - setMessage(status.getMessage(), - status.getSeverity() == IStatus.ERROR - ? IMessageProvider.ERROR : IMessageProvider.WARNING); - } else { - setErrorMessage(null); - setMessage(null); - } - } - - @Override - public boolean isPageComplete() { - // Ensure that the Finish button isn't enabled until - // the user has reached and completed this page - if (!mShown && mValues.createActivity) { - return false; - } - - return super.isPageComplete(); - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mCreateToggle) { - mValues.createActivity = mCreateToggle.getSelection(); - mList.setEnabled(mValues.createActivity); - } else if (source == mList) { - int index = mList.getSelectionIndex(); - if (index >= 0 && index < mTemplates.size()) { - File template = mTemplates.get(index); - mValues.activityValues.setTemplateLocation(template); - updatePreview(); - } - } - - validatePage(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/CreateFileChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/CreateFileChange.java deleted file mode 100644 index 3b41c36c2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/CreateFileChange.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.annotations.NonNull; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.google.common.io.Closeables; -import com.google.common.io.Files; -import com.google.common.io.InputSupplier; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.resource.ResourceChange; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.net.URI; - -/** Change which lazily copies a file */ -public class CreateFileChange extends ResourceChange { - private String mName; - private final IPath mPath; - private final File mSource; - - CreateFileChange(@NonNull String name, @NonNull IPath workspacePath, File source) { - mName = name; - mPath = workspacePath; - mSource = source; - } - - @Override - protected IResource getModifiedResource() { - return ResourcesPlugin.getWorkspace().getRoot().getFile(mPath); - } - - @Override - public String getName() { - return mName; - } - - @Override - public RefactoringStatus isValid(IProgressMonitor pm) - throws CoreException, OperationCanceledException { - RefactoringStatus result = new RefactoringStatus(); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(mPath); - URI location = file.getLocationURI(); - if (location == null) { - result.addFatalError("Unknown location " + file.getFullPath().toString()); - return result; - } - return result; - } - - @SuppressWarnings("resource") // Eclipse doesn't know about Guava's Closeables.closeQuietly - @Override - public Change perform(IProgressMonitor pm) throws CoreException { - InputSupplier<FileInputStream> supplier = Files.newInputStreamSupplier(mSource); - InputStream is = null; - try { - pm.beginTask("Creating file", 3); - IFile file = (IFile) getModifiedResource(); - - IContainer parent = file.getParent(); - if (parent != null && !parent.exists()) { - IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder( - parent.getFullPath()); - AdtUtils.ensureExists(folder); - } - - is = supplier.getInput(); - file.create(is, false, new SubProgressMonitor(pm, 1)); - pm.worked(1); - } catch (Exception ioe) { - AdtPlugin.log(ioe, null); - } finally { - Closeables.closeQuietly(is); - pm.done(); - } - return null; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmActivityToLayoutMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmActivityToLayoutMethod.java deleted file mode 100644 index fbd50e986..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmActivityToLayoutMethod.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectPage.ACTIVITY_NAME_SUFFIX; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectPage.LAYOUT_NAME_PREFIX; - -import com.android.ide.eclipse.adt.AdtUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to convert an Activity class name into - * a suitable layout name. - */ -public class FmActivityToLayoutMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - - String activityName = args.get(0).toString(); - - if (activityName.isEmpty()) { - return new SimpleScalar(""); - } - - // Strip off the end portion of the activity name. The user might be typing - // the activity name such that only a portion has been entered so far (e.g. - // "MainActivi") and we want to chop off that portion too such that we don't - // offer a layout name partially containing the activity suffix (e.g. "main_activi"). - int suffixStart = activityName.lastIndexOf(ACTIVITY_NAME_SUFFIX.charAt(0)); - if (suffixStart != -1 && activityName.regionMatches(suffixStart, ACTIVITY_NAME_SUFFIX, 0, - activityName.length() - suffixStart)) { - activityName = activityName.substring(0, suffixStart); - } - assert !activityName.endsWith(ACTIVITY_NAME_SUFFIX) : activityName; - - // Convert CamelCase convention used in activity class names to underlined convention - // used in layout name: - String name = LAYOUT_NAME_PREFIX + AdtUtils.camelCaseToUnderlines(activityName); - - return new SimpleScalar(name); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmCamelCaseToUnderscoreMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmCamelCaseToUnderscoreMethod.java deleted file mode 100644 index b85576577..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmCamelCaseToUnderscoreMethod.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.ide.eclipse.adt.AdtUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to convert an underscore name into a CamelCase name. - */ -public class FmCamelCaseToUnderscoreMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - return new SimpleScalar(AdtUtils.camelCaseToUnderlines(args.get(0).toString())); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmClassNameToResourceMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmClassNameToResourceMethod.java deleted file mode 100644 index 366de9afa..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmClassNameToResourceMethod.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectPage.ACTIVITY_NAME_SUFFIX; - -import com.android.ide.eclipse.adt.AdtUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Similar to {@link FmCamelCaseToUnderscoreMethod}, but strips off common class - * suffixes such as "Activity", "Fragment", etc. - */ -public class FmClassNameToResourceMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - - String name = args.get(0).toString(); - - if (name.isEmpty()) { - return new SimpleScalar(""); - } - - name = stripSuffix(name, ACTIVITY_NAME_SUFFIX); - name = stripSuffix(name, "Fragment"); //$NON-NLS-1$ - name = stripSuffix(name, "Service"); //$NON-NLS-1$ - name = stripSuffix(name, "Provider"); //$NON-NLS-1$ - - return new SimpleScalar(AdtUtils.camelCaseToUnderlines(name)); - } - - // Strip off the end portion of the activity name. The user might be typing - // the activity name such that only a portion has been entered so far (e.g. - // "MainActivi") and we want to chop off that portion too such that we don't - private static String stripSuffix(String name, String suffix) { - int suffixStart = name.lastIndexOf(suffix.charAt(0)); - if (suffixStart != -1 && name.regionMatches(suffixStart, suffix, 0, - name.length() - suffixStart)) { - name = name.substring(0, suffixStart); - } - assert !name.endsWith(suffix) : name; - - return name; - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlAttributeMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlAttributeMethod.java deleted file mode 100644 index 21f33b8d7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlAttributeMethod.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.utils.XmlUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to escape a string such that it can be used - * as an XML attribute (escaping ', ", & and <). - */ -public class FmEscapeXmlAttributeMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - String string = args.get(0).toString(); - return new SimpleScalar(XmlUtils.toXmlAttributeValue(string)); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlStringMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlStringMethod.java deleted file mode 100644 index 2255653a7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlStringMethod.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.ide.common.res2.ValueXmlHelper; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to escape a string such that it can be placed - * as text in a string resource file. - * This is similar to {@link FmEscapeXmlTextMethod}, but in addition to escaping - * < and & it also escapes characters such as quotes necessary for Android - *{@code <string>} elements. - */ -public class FmEscapeXmlStringMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - String string = args.get(0).toString(); - return new SimpleScalar(ValueXmlHelper.escapeResourceString(string)); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlTextMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlTextMethod.java deleted file mode 100644 index 55a4bc8ab..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlTextMethod.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.utils.XmlUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to escape a string such that it can be used - * as XML text (escaping < and &, but not ' and " etc). - */ -public class FmEscapeXmlTextMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - String string = args.get(0).toString(); - return new SimpleScalar(XmlUtils.toXmlTextValue(string)); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java deleted file mode 100644 index 09fa81c57..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to extract letters from a string; this will remove - * any whitespace, punctuation and digits. - */ -public class FmExtractLettersMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - String string = args.get(0).toString(); - StringBuilder sb = new StringBuilder(string.length()); - for (int i = 0, n = string.length(); i < n; i++) { - char c = string.charAt(i); - if (Character.isLetter(c)) { - sb.append(c); - } - } - return new SimpleScalar(sb.toString()); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmLayoutToActivityMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmLayoutToActivityMethod.java deleted file mode 100644 index 6514959f7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmLayoutToActivityMethod.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.AdtUtils.extractClassName; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectPage.ACTIVITY_NAME_SUFFIX; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectPage.LAYOUT_NAME_PREFIX; - -import com.android.ide.eclipse.adt.AdtUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to convert a layout name into an appropriate - * Activity class. - */ -public class FmLayoutToActivityMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - - String name = args.get(0).toString(); - - // Strip off the beginning portion of the layout name. The user might be typing - // the activity name such that only a portion has been entered so far (e.g. - // "MainActivi") and we want to chop off that portion too such that we don't - // offer a layout name partially containing the activity suffix (e.g. "main_activi"). - if (name.startsWith(LAYOUT_NAME_PREFIX)) { - name = name.substring(LAYOUT_NAME_PREFIX.length()); - } - - name = AdtUtils.underlinesToCamelCase(name); - String className = extractClassName(name); - if (className == null) { - className = "My"; - } - String activityName = className + ACTIVITY_NAME_SUFFIX; - - return new SimpleScalar(activityName); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmSlashedPackageNameMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmSlashedPackageNameMethod.java deleted file mode 100644 index 60a6531e6..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmSlashedPackageNameMethod.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to convert a package name (foo.bar) into - * a slashed path (foo/bar) - */ -public class FmSlashedPackageNameMethod implements TemplateMethodModel { - - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - - return new SimpleScalar(args.get(0).toString().replace('.', '/')); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmUnderscoreToCamelCaseMethod.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmUnderscoreToCamelCaseMethod.java deleted file mode 100644 index 26d4fadb4..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmUnderscoreToCamelCaseMethod.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.ide.eclipse.adt.AdtUtils; - -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -import java.util.List; - -/** - * Method invoked by FreeMarker to convert a CamelCase word into - * underscore_names. - */ -public class FmUnderscoreToCamelCaseMethod implements TemplateMethodModel { - @Override - public TemplateModel exec(List args) throws TemplateModelException { - if (args.size() != 1) { - throw new TemplateModelException("Wrong arguments"); - } - return new SimpleScalar(AdtUtils.underlinesToCamelCase(args.get(0).toString())); - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java deleted file mode 100644 index d806e7970..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; -import com.android.utils.Pair; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.wizard.IWizard; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Link; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.browser.IWebBrowser; - -import java.io.File; -import java.net.URL; -import java.util.List; - -class InstallDependencyPage extends WizardPage implements SelectionListener { - /** - * The compatibility library. This is the only library the templates - * currently support. The appearance of any other dependency in this - * template will be flagged as a validation error (and the user encouraged - * to upgrade to a newer ADT - */ - static final String SUPPORT_LIBRARY_NAME = "android-support-v4"; //$NON-NLS-1$ - - /** URL containing more info */ - private static final String URL = - "http://developer.android.com/tools/extras/support-library.html"; //$NON-NLS-1$ - - private Button mCheckButton; - private Button mInstallButton; - private Link mLink; - private TemplateMetadata mTemplate; - - InstallDependencyPage() { - super("dependency"); //$NON-NLS-1$ - setTitle("Install Dependencies"); - } - - void setTemplate(TemplateMetadata template) { - if (template != mTemplate) { - mTemplate = template; - if (getControl() != null) { - validatePage(); - } - } - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if (visible) { - updateVersionLabels(); - validatePage(); - } - } - - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - container.setLayout(new GridLayout(2, false)); - // Remaining contents are created lazily, since this page is always added to - // the page list, but typically not shown - - Label dependLabel = new Label(container, SWT.WRAP); - GridData gd_dependLabel = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 1); - gd_dependLabel.widthHint = NewTemplatePage.WIZARD_PAGE_WIDTH - 50; - dependLabel.setLayoutData(gd_dependLabel); - dependLabel.setText("This template depends on the Android Support library, which is " + - "either not installed, or the template depends on a more recent version than " + - "the one you have installed."); - - mLink = new Link(container, SWT.NONE); - mLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1)); - mLink.setText("<a href=\"" + URL + "\">" + URL + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - mLink.addSelectionListener(this); - - Label lblNewLabel_1 = new Label(container, SWT.NONE); - lblNewLabel_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); - - requiredLabel = new Label(container, SWT.NONE); - requiredLabel.setText("Required version:"); - - mRequiredVersion = new Label(container, SWT.NONE); - mRequiredVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); - - installedLabel = new Label(container, SWT.NONE); - installedLabel.setText("Installed version:"); - - mInstalledVersion = new Label(container, SWT.NONE); - mInstalledVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); - - Label lblNewLabel = new Label(container, SWT.NONE); - lblNewLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); - - Label descLabel = new Label(container, SWT.WRAP); - GridData gd_descLabel = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 1); - gd_descLabel.widthHint = 550; - descLabel.setLayoutData(gd_descLabel); - descLabel.setText( - "You can install or upgrade it by clicking the Install button below, or " + - "alternatively, you can install it outside of Eclipse with the SDK Manager, " + - "then click on \"Check Again\" to proceed."); - - mInstallButton = new Button(container, SWT.NONE); - mInstallButton.setText("Install/Upgrade"); - mInstallButton.addSelectionListener(this); - - mCheckButton = new Button(container, SWT.NONE); - mCheckButton.setText("Check Again"); - mCheckButton.addSelectionListener(this); - - mInstallButton.setFocus(); - } - - private void showNextPage() { - validatePage(); - if (isPageComplete()) { - // Finish button will be enabled now - mInstallButton.setEnabled(false); - mCheckButton.setEnabled(false); - - IWizard wizard = getWizard(); - IWizardPage next = wizard.getNextPage(this); - if (next != null) { - wizard.getContainer().showPage(next); - } - } - } - - @Override - public boolean isPageComplete() { - if (mTemplate == null) { - return true; - } - - return super.isPageComplete() && isInstalled(); - } - - private boolean isInstalled() { - return isInstalled(mTemplate.getDependencies()); - } - - static String sCachedName; - static int sCachedVersion; - private Label requiredLabel; - private Label installedLabel; - private Label mRequiredVersion; - private Label mInstalledVersion; - - public static boolean isInstalled(List<Pair<String, Integer>> dependencies) { - for (Pair<String, Integer> dependency : dependencies) { - String name = dependency.getFirst(); - int required = dependency.getSecond(); - - int installed = -1; - if (SUPPORT_LIBRARY_NAME.equals(name)) { - installed = getInstalledSupportLibVersion(); - } - - if (installed == -1) { - return false; - } - if (required > installed) { - return false; - } - } - - return true; - } - - private static int getInstalledSupportLibVersion() { - if (SUPPORT_LIBRARY_NAME.equals(sCachedName)) { - return sCachedVersion; - } else { - int version = AddSupportJarAction.getInstalledRevision(); - sCachedName = SUPPORT_LIBRARY_NAME; - sCachedVersion = version; - return version; - } - } - - private void updateVersionLabels() { - int version = getInstalledSupportLibVersion(); - if (version == -1) { - mInstalledVersion.setText("Not installed"); - } else { - mInstalledVersion.setText(Integer.toString(version)); - } - - if (mTemplate != null) { - for (Pair<String, Integer> dependency : mTemplate.getDependencies()) { - String name = dependency.getFirst(); - if (name.equals(SUPPORT_LIBRARY_NAME)) { - int required = dependency.getSecond(); - mRequiredVersion.setText(Integer.toString(required)); - break; - } - } - } - } - - private void validatePage() { - if (mTemplate == null) { - return; - } - - IStatus status = null; - - List<Pair<String, Integer>> dependencies = mTemplate.getDependencies(); - if (dependencies.size() > 1 || dependencies.size() == 1 - && !dependencies.get(0).getFirst().equals(SUPPORT_LIBRARY_NAME)) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "Unsupported template dependency: Upgrade your Android Eclipse plugin"); - } - - setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); - if (status != null) { - setMessage(status.getMessage(), - status.getSeverity() == IStatus.ERROR - ? IMessageProvider.ERROR : IMessageProvider.WARNING); - } else { - setErrorMessage(null); - setMessage(null); - } - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - Object source = e.getSource(); - if (source == mCheckButton) { - sCachedName = null; - if (isInstalled()) { - showNextPage(); - } - updateVersionLabels(); - } else if (source == mInstallButton) { - sCachedName = null; - for (Pair<String, Integer> dependency : mTemplate.getDependencies()) { - String name = dependency.getFirst(); - if (SUPPORT_LIBRARY_NAME.equals(name)) { - int version = dependency.getSecond(); - File installed = AddSupportJarAction.installSupport(version); - if (installed != null) { - showNextPage(); - } - updateVersionLabels(); - } - } - } else if (source == mLink) { - try { - IWorkbench workbench = PlatformUI.getWorkbench(); - IWebBrowser browser = workbench.getBrowserSupport().getExternalBrowser(); - browser.openURL(new URL(URL)); - } catch (Exception ex) { - String message = String.format("Could not open browser. Vist\n%1$s\ninstead.", - URL); - MessageDialog.openError(getShell(), "Browser Error", message); - } - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java deleted file mode 100644 index b33d65bb7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_BUILD_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API_LEVEL; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_TARGET_API; -import static org.eclipse.core.resources.IResource.DEPTH_INFINITE; - -import com.android.annotations.NonNull; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.ui.IWorkbench; - -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.Set; - -/** - * Wizard for creating new activities. This is a hybrid between a New Project - * Wizard and a New Template Wizard: it has the "Activity selector" page from - * the New Project Wizard, which is used to dynamically select a wizard for the - * second page, but beyond that it runs the normal template wizard when it comes - * time to create the template. - */ -public class NewActivityWizard extends TemplateWizard { - private NewTemplatePage mTemplatePage; - private ActivityPage mActivityPage; - private NewProjectWizardState mValues; - private NewTemplateWizardState mActivityValues; - protected boolean mOnlyActivities; - - /** Creates a new {@link NewActivityWizard} */ - public NewActivityWizard() { - mOnlyActivities = true; - } - - @Override - protected boolean shouldAddIconPage() { - return mActivityValues.getIconState() != null; - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - super.init(workbench, selection); - - setWindowTitle(mOnlyActivities ? "New Activity" : "New Android Object"); - - mValues = new NewProjectWizardState(); - mActivityPage = new ActivityPage(mValues, mOnlyActivities, false); - - mActivityValues = mValues.activityValues; - List<IProject> projects = AdtUtils.getSelectedProjects(selection); - if (projects.size() == 1) { - mActivityValues.project = projects.get(0); - } - } - - @Override - public void addPages() { - super.addPages(); - addPage(mActivityPage); - } - - @Override - public IWizardPage getNextPage(IWizardPage page) { - if (page == mActivityPage) { - if (mTemplatePage == null) { - Set<String> hidden = mActivityValues.hidden; - hidden.add(ATTR_PACKAGE_NAME); - hidden.add(ATTR_MIN_API); - hidden.add(ATTR_MIN_API_LEVEL); - hidden.add(ATTR_TARGET_API); - hidden.add(ATTR_BUILD_API); - - mTemplatePage = new NewTemplatePage(mActivityValues, true); - addPage(mTemplatePage); - } - return mTemplatePage; - } else if (page == mTemplatePage && shouldAddIconPage()) { - WizardPage iconPage = getIconPage(mActivityValues.getIconState()); - mActivityValues.updateIconState(mTemplatePage.getEvaluator()); - return iconPage; - } else if (page == mTemplatePage - || shouldAddIconPage() && page == getIconPage(mActivityValues.getIconState())) { - TemplateMetadata template = mActivityValues.getTemplateHandler().getTemplate(); - if (template != null) { - if (InstallDependencyPage.isInstalled(template.getDependencies())) { - return getPreviewPage(mActivityValues); - } else { - return getDependencyPage(template, true); - } - } - } else { - TemplateMetadata template = mActivityValues.getTemplateHandler().getTemplate(); - if (template != null && page == getDependencyPage(template, false)) { - return getPreviewPage(mActivityValues); - } - } - - return super.getNextPage(page); - } - - @Override - public boolean canFinish() { - // Deal with lazy creation of some pages: these may not be in the page-list yet - // since they are constructed lazily, so consider that option here. - if (mTemplatePage == null || !mTemplatePage.isPageComplete()) { - return false; - } - - return super.canFinish(); - } - - @Override - public boolean performFinish(IProgressMonitor monitor) throws InvocationTargetException { - boolean success = super.performFinish(monitor); - - if (success) { - List<Runnable> finalizingTasks = getFinalizingActions(); - for (Runnable r : finalizingTasks) { - r.run(); - } - return true; - } - return false; - } - - @Override - @NonNull - protected IProject getProject() { - return mActivityValues.project; - } - - @Override - @NonNull - protected List<String> getFilesToOpen() { - TemplateHandler activityTemplate = mActivityValues.getTemplateHandler(); - return activityTemplate.getFilesToOpen(); - } - - @Override - @NonNull - protected List<Runnable> getFinalizingActions() { - TemplateHandler activityTemplate = mActivityValues.getTemplateHandler(); - return activityTemplate.getFinalizingActions(); - } - - @Override - protected List<Change> computeChanges() { - return mActivityValues.computeChanges(); - } - - /** Wizard for creating other Android components */ - public static class OtherWizard extends NewActivityWizard { - /** Create new {@link OtherWizard} */ - public OtherWizard() { - mOnlyActivities = false; - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java deleted file mode 100644 index 14f59c00d..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - - -import static com.android.SdkConstants.ATTR_ID; -import static com.android.ide.eclipse.adt.AdtUtils.extractClassName; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewTemplatePage.WIZARD_PAGE_WIDTH; - -import com.android.annotations.Nullable; -import com.android.sdklib.SdkVersionInfo; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage; -import com.android.ide.eclipse.adt.internal.wizards.newproject.ProjectNamePage; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.fieldassist.ControlDecoration; -import org.eclipse.jface.fieldassist.FieldDecoration; -import org.eclipse.jface.fieldassist.FieldDecorationRegistry; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * First wizard page in the "New Project From Template" wizard - */ -public class NewProjectPage extends WizardPage - implements ModifyListener, SelectionListener, FocusListener { - private static final int FIELD_WIDTH = 300; - private static final String SAMPLE_PACKAGE_PREFIX = "com.example."; //$NON-NLS-1$ - /** Suffix added by default to activity names */ - static final String ACTIVITY_NAME_SUFFIX = "Activity"; //$NON-NLS-1$ - /** Prefix added to default layout names */ - static final String LAYOUT_NAME_PREFIX = "activity_"; //$NON-NLS-1$ - private static final int INITIAL_MIN_SDK = 8; - - private final NewProjectWizardState mValues; - private Map<String, Integer> mMinNameToApi; - private Parameter mThemeParameter; - private Combo mThemeCombo; - - private Text mProjectText; - private Text mPackageText; - private Text mApplicationText; - private Combo mMinSdkCombo; - private Combo mTargetSdkCombo; - private Combo mBuildSdkCombo; - private Label mHelpIcon; - private Label mTipLabel; - - private boolean mIgnore; - private ControlDecoration mApplicationDec; - private ControlDecoration mProjectDec; - private ControlDecoration mPackageDec; - private ControlDecoration mBuildTargetDec; - private ControlDecoration mMinSdkDec; - private ControlDecoration mTargetSdkDec; - private ControlDecoration mThemeDec; - - NewProjectPage(NewProjectWizardState values) { - super("newAndroidApp"); //$NON-NLS-1$ - mValues = values; - setTitle("New Android Application"); - setDescription("Creates a new Android Application"); - } - - @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - GridLayout gl_container = new GridLayout(4, false); - gl_container.horizontalSpacing = 10; - container.setLayout(gl_container); - - Label applicationLabel = new Label(container, SWT.NONE); - applicationLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - applicationLabel.setText("Application Name:"); - - mApplicationText = new Text(container, SWT.BORDER); - GridData gdApplicationText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1); - gdApplicationText.widthHint = FIELD_WIDTH; - mApplicationText.setLayoutData(gdApplicationText); - mApplicationText.addModifyListener(this); - mApplicationText.addFocusListener(this); - mApplicationDec = createFieldDecoration(mApplicationText, - "The application name is shown in the Play Store, as well as in the " + - "Manage Application list in Settings."); - - Label projectLabel = new Label(container, SWT.NONE); - projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - projectLabel.setText("Project Name:"); - mProjectText = new Text(container, SWT.BORDER); - GridData gdProjectText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1); - gdProjectText.widthHint = FIELD_WIDTH; - mProjectText.setLayoutData(gdProjectText); - mProjectText.addModifyListener(this); - mProjectText.addFocusListener(this); - mProjectDec = createFieldDecoration(mProjectText, - "The project name is only used by Eclipse, but must be unique within the " + - "workspace. This can typically be the same as the application name."); - - Label packageLabel = new Label(container, SWT.NONE); - packageLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - packageLabel.setText("Package Name:"); - - mPackageText = new Text(container, SWT.BORDER); - GridData gdPackageText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1); - gdPackageText.widthHint = FIELD_WIDTH; - mPackageText.setLayoutData(gdPackageText); - mPackageText.addModifyListener(this); - mPackageText.addFocusListener(this); - mPackageDec = createFieldDecoration(mPackageText, - "The package name must be a unique identifier for your application.\n" + - "It is typically not shown to users, but it *must* stay the same " + - "for the lifetime of your application; it is how multiple versions " + - "of the same application are considered the \"same app\".\nThis is " + - "typically the reverse domain name of your organization plus one or " + - "more application identifiers, and it must be a valid Java package " + - "name."); - new Label(container, SWT.NONE); - - new Label(container, SWT.NONE); - new Label(container, SWT.NONE); - new Label(container, SWT.NONE); - - // Min SDK - - Label minSdkLabel = new Label(container, SWT.NONE); - minSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - minSdkLabel.setText("Minimum Required SDK:"); - - mMinSdkCombo = new Combo(container, SWT.READ_ONLY); - GridData gdMinSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); - gdMinSdkCombo.widthHint = FIELD_WIDTH; - mMinSdkCombo.setLayoutData(gdMinSdkCombo); - - // Pick most recent platform - IAndroidTarget[] targets = getCompilationTargets(); - mMinNameToApi = Maps.newHashMap(); - List<String> targetLabels = new ArrayList<String>(targets.length); - for (IAndroidTarget target : targets) { - String targetLabel; - if (target.isPlatform() - && target.getVersion().getApiLevel() <= AdtUtils.getHighestKnownApiLevel()) { - targetLabel = AdtUtils.getAndroidName(target.getVersion().getApiLevel()); - } else { - targetLabel = AdtUtils.getTargetLabel(target); - } - targetLabels.add(targetLabel); - mMinNameToApi.put(targetLabel, target.getVersion().getApiLevel()); - } - - List<String> codeNames = Lists.newArrayList(); - int buildTargetIndex = -1; - for (int i = 0, n = targets.length; i < n; i++) { - IAndroidTarget target = targets[i]; - AndroidVersion version = target.getVersion(); - int apiLevel = version.getApiLevel(); - if (version.isPreview()) { - String codeName = version.getCodename(); - String targetLabel = codeName + " Preview"; - codeNames.add(targetLabel); - mMinNameToApi.put(targetLabel, apiLevel); - } else if (target.isPlatform() - && (mValues.target == null || - apiLevel > mValues.target.getVersion().getApiLevel())) { - mValues.target = target; - buildTargetIndex = i; - } - } - List<String> labels = new ArrayList<String>(24); - for (String label : AdtUtils.getKnownVersions()) { - labels.add(label); - } - assert labels.size() >= 15; // *Known* versions to ADT, not installed/available versions - for (String codeName : codeNames) { - labels.add(codeName); - } - String[] versions = labels.toArray(new String[labels.size()]); - mMinSdkCombo.setItems(versions); - if (mValues.target != null && mValues.target.getVersion().isPreview()) { - mValues.minSdk = mValues.target.getVersion().getCodename(); - mMinSdkCombo.setText(mValues.minSdk); - mValues.iconState.minSdk = mValues.target.getVersion().getApiLevel(); - mValues.minSdkLevel = mValues.iconState.minSdk; - } else { - mMinSdkCombo.select(INITIAL_MIN_SDK - 1); - mValues.minSdk = Integer.toString(INITIAL_MIN_SDK); - mValues.minSdkLevel = INITIAL_MIN_SDK; - mValues.iconState.minSdk = INITIAL_MIN_SDK; - } - mMinSdkCombo.addSelectionListener(this); - mMinSdkCombo.addFocusListener(this); - mMinSdkDec = createFieldDecoration(mMinSdkCombo, - "Choose the lowest version of Android that your application will support. Lower " + - "API levels target more devices, but means fewer features are available. By " + - "targeting API 8 and later, you reach approximately 95% of the market."); - new Label(container, SWT.NONE); - - // Target SDK - Label targetSdkLabel = new Label(container, SWT.NONE); - targetSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - targetSdkLabel.setText("Target SDK:"); - - mTargetSdkCombo = new Combo(container, SWT.READ_ONLY); - GridData gdTargetSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); - gdTargetSdkCombo.widthHint = FIELD_WIDTH; - mTargetSdkCombo.setLayoutData(gdTargetSdkCombo); - - mTargetSdkCombo.setItems(versions); - mTargetSdkCombo.select(mValues.targetSdkLevel - 1); - - mTargetSdkCombo.addSelectionListener(this); - mTargetSdkCombo.addFocusListener(this); - mTargetSdkDec = createFieldDecoration(mTargetSdkCombo, - "Choose the highest API level that the application is known to work with. " + - "This attribute informs the system that you have tested against the target " + - "version and the system should not enable any compatibility behaviors to " + - "maintain your app's forward-compatibility with the target version. " + - "The application is still able to run on older versions " + - "(down to minSdkVersion). Your application may look dated if you are not " + - "targeting the current version."); - new Label(container, SWT.NONE); - - // Build Version - - Label buildSdkLabel = new Label(container, SWT.NONE); - buildSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - buildSdkLabel.setText("Compile With:"); - - mBuildSdkCombo = new Combo(container, SWT.READ_ONLY); - GridData gdBuildSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); - gdBuildSdkCombo.widthHint = FIELD_WIDTH; - mBuildSdkCombo.setLayoutData(gdBuildSdkCombo); - mBuildSdkCombo.setData(targets); - mBuildSdkCombo.setItems(targetLabels.toArray(new String[targetLabels.size()])); - if (buildTargetIndex != -1) { - mBuildSdkCombo.select(buildTargetIndex); - } - - mBuildSdkCombo.addSelectionListener(this); - mBuildSdkCombo.addFocusListener(this); - mBuildTargetDec = createFieldDecoration(mBuildSdkCombo, - "Choose a target API to compile your code against, from your installed SDKs. " + - "This is typically the most recent version, or the first version that supports " + - "all the APIs you want to directly access without reflection."); - new Label(container, SWT.NONE); - - TemplateMetadata metadata = mValues.template.getTemplate(); - if (metadata != null) { - mThemeParameter = metadata.getParameter("baseTheme"); //$NON-NLS-1$ - if (mThemeParameter != null && mThemeParameter.element != null) { - Label themeLabel = new Label(container, SWT.NONE); - themeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1)); - themeLabel.setText("Theme:"); - - mThemeCombo = NewTemplatePage.createOptionCombo(mThemeParameter, container, - mValues.parameters, this, this); - GridData gdThemeCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); - gdThemeCombo.widthHint = FIELD_WIDTH; - mThemeCombo.setLayoutData(gdThemeCombo); - new Label(container, SWT.NONE); - - mThemeDec = createFieldDecoration(mThemeCombo, - "Choose the base theme to use for the application"); - } - } - - new Label(container, SWT.NONE); - new Label(container, SWT.NONE); - new Label(container, SWT.NONE); - new Label(container, SWT.NONE); - - Label label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 4, 1)); - - mHelpIcon = new Label(container, SWT.NONE); - mHelpIcon.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1)); - Image icon = IconFactory.getInstance().getIcon("quickfix"); - mHelpIcon.setImage(icon); - mHelpIcon.setVisible(false); - - mTipLabel = new Label(container, SWT.WRAP); - mTipLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); - - // Reserve space for 4 lines - mTipLabel.setText("\n\n\n\n"); //$NON-NLS-1$ - - // Reserve enough width to accommodate the various wizard pages up front - // (since they are created lazily, and we don't want the wizard to dynamically - // resize itself for small size adjustments as each successive page is slightly - // larger) - Label dummy = new Label(container, SWT.NONE); - GridData data = new GridData(); - data.horizontalSpan = 4; - data.widthHint = WIZARD_PAGE_WIDTH; - dummy.setLayoutData(data); - } - - /** - * Updates the theme selection such that it's valid for the current build - * and min sdk targets. Also runs {@link #validatePage} in case no valid entry was found. - * Does nothing if called on a template that does not supply a theme. - */ - void updateTheme() { - if (mThemeParameter != null) { - // Pick the highest theme version that works for the current SDK level - Parameter parameter = NewTemplatePage.getParameter(mThemeCombo); - assert parameter == mThemeParameter; - if (parameter != null) { - String[] optionIds = (String[]) mThemeCombo.getData(ATTR_ID); - for (int index = optionIds.length - 1; index >= 0; index--) { - IStatus status = NewTemplatePage.validateCombo(null, mThemeParameter, - index, mValues.minSdkLevel, mValues.getBuildApi()); - if (status == null || status.isOK()) { - String optionId = optionIds[index]; - parameter.value = optionId; - parameter.edited = optionId != null && !optionId.toString().isEmpty(); - mValues.parameters.put(parameter.id, optionId); - try { - mIgnore = true; - mThemeCombo.select(index); - } finally { - mIgnore = false; - } - break; - } - } - } - - validatePage(); - } - } - - private IAndroidTarget[] getCompilationTargets() { - Sdk current = Sdk.getCurrent(); - if (current == null) { - return new IAndroidTarget[0]; - } - IAndroidTarget[] targets = current.getTargets(); - List<IAndroidTarget> list = new ArrayList<IAndroidTarget>(); - - for (IAndroidTarget target : targets) { - if (target.isPlatform() == false && - (target.getOptionalLibraries() == null || - target.getOptionalLibraries().length == 0)) { - continue; - } - list.add(target); - } - - return list.toArray(new IAndroidTarget[list.size()]); - } - - private ControlDecoration createFieldDecoration(Control control, String description) { - ControlDecoration dec = new ControlDecoration(control, SWT.LEFT); - dec.setMarginWidth(2); - FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault(). - getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION); - dec.setImage(errorFieldIndicator.getImage()); - dec.setDescriptionText(description); - control.setToolTipText(description); - - return dec; - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - - // DURING DEVELOPMENT ONLY - //if (assertionsEnabled()) { - // String uniqueProjectName = AdtUtils.getUniqueProjectName("Test", ""); - // mProjectText.setText(uniqueProjectName); - // mPackageText.setText("test.pkg"); - //} - - validatePage(); - } - - // ---- Implements ModifyListener ---- - - @Override - public void modifyText(ModifyEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mProjectText) { - mValues.projectName = mProjectText.getText(); - updateProjectLocation(mValues.projectName); - mValues.projectModified = true; - - try { - mIgnore = true; - if (!mValues.applicationModified) { - mValues.applicationName = mValues.projectName; - mApplicationText.setText(mValues.projectName); - } - updateActivityNames(mValues.projectName); - } finally { - mIgnore = false; - } - suggestPackage(mValues.projectName); - } else if (source == mPackageText) { - mValues.packageName = mPackageText.getText(); - mValues.packageModified = true; - } else if (source == mApplicationText) { - mValues.applicationName = mApplicationText.getText(); - mValues.applicationModified = true; - - try { - mIgnore = true; - if (!mValues.projectModified) { - mValues.projectName = appNameToProjectName(mValues.applicationName); - mProjectText.setText(mValues.projectName); - updateProjectLocation(mValues.projectName); - } - updateActivityNames(mValues.applicationName); - } finally { - mIgnore = false; - } - suggestPackage(mValues.applicationName); - } - - validatePage(); - } - - private String appNameToProjectName(String appName) { - // Strip out whitespace (and capitalize subsequent words where spaces were removed - boolean upcaseNext = false; - StringBuilder sb = new StringBuilder(appName.length()); - for (int i = 0, n = appName.length(); i < n; i++) { - char c = appName.charAt(i); - if (c == ' ') { - upcaseNext = true; - } else if (upcaseNext) { - sb.append(Character.toUpperCase(c)); - upcaseNext = false; - } else { - sb.append(c); - } - } - - appName = sb.toString().trim(); - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IStatus nameStatus = workspace.validateName(appName, IResource.PROJECT); - if (nameStatus.isOK()) { - return appName; - } - - sb = new StringBuilder(appName.length()); - for (int i = 0, n = appName.length(); i < n; i++) { - char c = appName.charAt(i); - if (Character.isLetterOrDigit(c) || c == '.' || c == '-') { - sb.append(c); - } - } - - return sb.toString().trim(); - } - - /** If the project should be created in the workspace, then update the project location - * based on the project name. */ - private void updateProjectLocation(String projectName) { - if (projectName == null) { - projectName = ""; - } - - if (mValues.useDefaultLocation) { - IPath workspace = Platform.getLocation(); - String projectLocation = workspace.append(projectName).toOSString(); - mValues.projectLocation = projectLocation; - } - } - - private void updateActivityNames(String name) { - try { - mIgnore = true; - if (!mValues.activityNameModified) { - mValues.activityName = extractClassName(name) + ACTIVITY_NAME_SUFFIX; - } - if (!mValues.activityTitleModified) { - mValues.activityTitle = name; - } - } finally { - mIgnore = false; - } - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mMinSdkCombo) { - mValues.minSdk = getSelectedMinSdk(); - Integer minSdk = mMinNameToApi.get(mValues.minSdk); - if (minSdk == null) { - try { - minSdk = Integer.parseInt(mValues.minSdk); - } catch (NumberFormatException nufe) { - // If not a number, then the string is a codename, so treat it - // as a preview version. - minSdk = SdkVersionInfo.HIGHEST_KNOWN_API + 1; - } - } - mValues.iconState.minSdk = minSdk.intValue(); - mValues.minSdkLevel = minSdk.intValue(); - - // If higher than build target, adjust build target - if (mValues.minSdkLevel > mValues.getBuildApi()) { - // Try to find a build target with an adequate build API - IAndroidTarget[] targets = (IAndroidTarget[]) mBuildSdkCombo.getData(); - IAndroidTarget best = null; - int bestApi = Integer.MAX_VALUE; - int bestTargetIndex = -1; - for (int i = 0; i < targets.length; i++) { - IAndroidTarget target = targets[i]; - if (!target.isPlatform()) { - continue; - } - int api = target.getVersion().getApiLevel(); - if (api >= mValues.minSdkLevel && api < bestApi) { - best = target; - bestApi = api; - bestTargetIndex = i; - } - } - - if (best != null) { - assert bestTargetIndex != -1; - mValues.target = best; - try { - mIgnore = true; - mBuildSdkCombo.select(bestTargetIndex); - } finally { - mIgnore = false; - } - } - } - - // If higher than targetSdkVersion, adjust targetSdkVersion - if (mValues.minSdkLevel > mValues.targetSdkLevel) { - mValues.targetSdkLevel = mValues.minSdkLevel; - try { - mIgnore = true; - setSelectedTargetSdk(mValues.targetSdkLevel); - } finally { - mIgnore = false; - } - } - } else if (source == mBuildSdkCombo) { - mValues.target = getSelectedBuildTarget(); - - // If lower than min sdk target, adjust min sdk target - if (mValues.target.getVersion().isPreview()) { - mValues.minSdk = mValues.target.getVersion().getCodename(); - try { - mIgnore = true; - mMinSdkCombo.setText(mValues.minSdk); - } finally { - mIgnore = false; - } - } else { - String minSdk = mValues.minSdk; - int buildApiLevel = mValues.target.getVersion().getApiLevel(); - if (minSdk != null && !minSdk.isEmpty() - && Character.isDigit(minSdk.charAt(0)) - && buildApiLevel < Integer.parseInt(minSdk)) { - mValues.minSdk = Integer.toString(buildApiLevel); - try { - mIgnore = true; - setSelectedMinSdk(buildApiLevel); - } finally { - mIgnore = false; - } - } - } - } else if (source == mTargetSdkCombo) { - mValues.targetSdkLevel = getSelectedTargetSdk(); - } - - validatePage(); - } - - private String getSelectedMinSdk() { - // If you're using a preview build, such as android-JellyBean, you have - // to use the codename, e.g. JellyBean, as the minimum SDK as well. - IAndroidTarget buildTarget = getSelectedBuildTarget(); - if (buildTarget != null && buildTarget.getVersion().isPreview()) { - return buildTarget.getVersion().getCodename(); - } - - // +1: First API level (at index 0) is 1 - return Integer.toString(mMinSdkCombo.getSelectionIndex() + 1); - } - - private int getSelectedTargetSdk() { - // +1: First API level (at index 0) is 1 - return mTargetSdkCombo.getSelectionIndex() + 1; - } - - private void setSelectedMinSdk(int api) { - mMinSdkCombo.select(api - 1); // -1: First API level (at index 0) is 1 - } - - private void setSelectedTargetSdk(int api) { - mTargetSdkCombo.select(api - 1); // -1: First API level (at index 0) is 1 - } - - @Nullable - private IAndroidTarget getSelectedBuildTarget() { - IAndroidTarget[] targets = (IAndroidTarget[]) mBuildSdkCombo.getData(); - int index = mBuildSdkCombo.getSelectionIndex(); - if (index >= 0 && index < targets.length) { - return targets[index]; - } else { - return null; - } - } - - private void suggestPackage(String original) { - if (!mValues.packageModified) { - // Create default package name - StringBuilder sb = new StringBuilder(); - sb.append(SAMPLE_PACKAGE_PREFIX); - appendPackage(sb, original); - - String pkg = sb.toString(); - if (pkg.endsWith(".")) { //$NON-NLS-1$ - pkg = pkg.substring(0, pkg.length() - 1); - } - mValues.packageName = pkg; - try { - mIgnore = true; - mPackageText.setText(mValues.packageName); - } finally { - mIgnore = false; - } - } - } - - private static void appendPackage(StringBuilder sb, String string) { - for (int i = 0, n = string.length(); i < n; i++) { - char c = string.charAt(i); - if (i == 0 && Character.isJavaIdentifierStart(c) - || i != 0 && Character.isJavaIdentifierPart(c)) { - sb.append(Character.toLowerCase(c)); - } else if ((c == '.') - && (sb.length() > 0 && sb.charAt(sb.length() - 1) != '.')) { - sb.append('.'); - } else if (c == '-') { - sb.append('_'); - } - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - // ---- Implements FocusListener ---- - - @Override - public void focusGained(FocusEvent e) { - Object source = e.getSource(); - String tip = ""; - if (source == mApplicationText) { - tip = mApplicationDec.getDescriptionText(); - } else if (source == mProjectText) { - tip = mProjectDec.getDescriptionText(); - } else if (source == mBuildSdkCombo) { - tip = mBuildTargetDec.getDescriptionText(); - } else if (source == mMinSdkCombo) { - tip = mMinSdkDec.getDescriptionText(); - } else if (source == mPackageText) { - tip = mPackageDec.getDescriptionText(); - if (mPackageText.getText().startsWith(SAMPLE_PACKAGE_PREFIX)) { - int length = SAMPLE_PACKAGE_PREFIX.length(); - if (mPackageText.getText().length() > length - && SAMPLE_PACKAGE_PREFIX.endsWith(".")) { //$NON-NLS-1$ - length--; - } - mPackageText.setSelection(0, length); - } - } else if (source == mTargetSdkCombo) { - tip = mTargetSdkDec.getDescriptionText(); - } else if (source == mThemeCombo) { - tip = mThemeDec.getDescriptionText(); - } - mTipLabel.setText(tip); - mHelpIcon.setVisible(tip.length() > 0); - } - - @Override - public void focusLost(FocusEvent e) { - mTipLabel.setText(""); - mHelpIcon.setVisible(false); - } - - // Validation - - private void validatePage() { - IStatus status = mValues.template.validateTemplate(mValues.minSdkLevel, - mValues.getBuildApi()); - if (status != null && !status.isOK()) { - updateDecorator(mApplicationDec, null, true); - updateDecorator(mPackageDec, null, true); - updateDecorator(mProjectDec, null, true); - updateDecorator(mThemeDec, null, true); - /* These never get marked with errors: - updateDecorator(mBuildTargetDec, null, true); - updateDecorator(mMinSdkDec, null, true); - updateDecorator(mTargetSdkDec, null, true); - */ - } else { - IStatus appStatus = validateAppName(); - if (appStatus != null && (status == null - || appStatus.getSeverity() > status.getSeverity())) { - status = appStatus; - } - - IStatus projectStatus = validateProjectName(); - if (projectStatus != null && (status == null - || projectStatus.getSeverity() > status.getSeverity())) { - status = projectStatus; - } - - IStatus packageStatus = validatePackageName(); - if (packageStatus != null && (status == null - || packageStatus.getSeverity() > status.getSeverity())) { - status = packageStatus; - } - - IStatus locationStatus = ProjectContentsPage.validateLocationInWorkspace(mValues); - if (locationStatus != null && (status == null - || locationStatus.getSeverity() > status.getSeverity())) { - status = locationStatus; - } - - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mValues.target == null) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "Select an Android build target version"); - } - } - - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mValues.minSdk == null || mValues.minSdk.isEmpty()) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "Select a minimum SDK version"); - } else { - AndroidVersion version = mValues.target.getVersion(); - if (version.isPreview()) { - if (version.getCodename().equals(mValues.minSdk) == false) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Preview platforms require the min SDK version to match their codenames."); - } - } else if (mValues.target.getVersion().compareTo( - mValues.minSdkLevel, - version.isPreview() ? mValues.minSdk : null) < 0) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "The minimum SDK version is higher than the build target version"); - } - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mValues.targetSdkLevel < mValues.minSdkLevel) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "The target SDK version should be at least as high as the minimum SDK version"); - } - } - } - } - - IStatus themeStatus = validateTheme(); - if (themeStatus != null && (status == null - || themeStatus.getSeverity() > status.getSeverity())) { - status = themeStatus; - } - } - - setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); - if (status != null) { - setMessage(status.getMessage(), - status.getSeverity() == IStatus.ERROR - ? IMessageProvider.ERROR : IMessageProvider.WARNING); - } else { - setErrorMessage(null); - setMessage(null); - } - } - - private IStatus validateAppName() { - String appName = mValues.applicationName; - IStatus status = null; - if (appName == null || appName.isEmpty()) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Enter an application name (shown in launcher)"); - } else if (Character.isLowerCase(mValues.applicationName.charAt(0))) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "The application name for most apps begins with an uppercase letter"); - } - - updateDecorator(mApplicationDec, status, true); - - return status; - } - - private IStatus validateProjectName() { - IStatus status = ProjectNamePage.validateProjectName(mValues.projectName); - updateDecorator(mProjectDec, status, true); - - return status; - } - - private IStatus validatePackageName() { - IStatus status; - if (mValues.packageName == null || mValues.packageName.startsWith(SAMPLE_PACKAGE_PREFIX)) { - if (mValues.packageName != null - && !mValues.packageName.equals(SAMPLE_PACKAGE_PREFIX)) { - status = ApplicationInfoPage.validatePackage(mValues.packageName); - if (status == null || status.isOK()) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - String.format("The prefix '%1$s' is meant as a placeholder and should " + - "not be used", SAMPLE_PACKAGE_PREFIX)); - } - } else { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Package name must be specified."); - } - } else { - status = ApplicationInfoPage.validatePackage(mValues.packageName); - } - - updateDecorator(mPackageDec, status, true); - - return status; - } - - private IStatus validateTheme() { - IStatus status = null; - - if (mThemeParameter != null) { - status = NewTemplatePage.validateCombo(null, mThemeParameter, - mThemeCombo.getSelectionIndex(), mValues.minSdkLevel, - mValues.getBuildApi()); - - updateDecorator(mThemeDec, status, true); - } - - return status; - } - - private void updateDecorator(ControlDecoration decorator, IStatus status, boolean hasInfo) { - if (hasInfo) { - int severity = status != null ? status.getSeverity() : IStatus.OK; - setDecoratorType(decorator, severity); - } else { - if (status == null || status.isOK()) { - decorator.hide(); - } else { - decorator.show(); - } - } - } - - private void setDecoratorType(ControlDecoration decorator, int severity) { - String id; - if (severity == IStatus.ERROR) { - id = FieldDecorationRegistry.DEC_ERROR; - } else if (severity == IStatus.WARNING) { - id = FieldDecorationRegistry.DEC_WARNING; - } else { - id = FieldDecorationRegistry.DEC_INFORMATION; - } - FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault(). - getFieldDecoration(id); - decorator.setImage(errorFieldIndicator.getImage()); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java deleted file mode 100644 index d350a00dd..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static org.eclipse.core.resources.IResource.DEPTH_INFINITE; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.assetstudiolib.GraphicGenerator; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; -import com.android.ide.eclipse.adt.internal.assetstudio.AssetType; -import com.android.ide.eclipse.adt.internal.assetstudio.ConfigureAssetSetPage; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.ProjectHelper; -import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreator; -import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreator.ProjectPopulator; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.ui.IWorkbench; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Wizard for creating new projects - */ -public class NewProjectWizard extends TemplateWizard { - private static final String PARENT_ACTIVITY_CLASS = "parentActivityClass"; //$NON-NLS-1$ - private static final String ACTIVITY_TITLE = "activityTitle"; //$NON-NLS-1$ - static final String IS_LAUNCHER = "isLauncher"; //$NON-NLS-1$ - static final String IS_NEW_PROJECT = "isNewProject"; //$NON-NLS-1$ - static final String IS_LIBRARY_PROJECT = "isLibraryProject"; //$NON-NLS-1$ - static final String ATTR_COPY_ICONS = "copyIcons"; //$NON-NLS-1$ - static final String ATTR_TARGET_API = "targetApi"; //$NON-NLS-1$ - static final String ATTR_MIN_API = "minApi"; //$NON-NLS-1$ - static final String ATTR_MIN_BUILD_API = "minBuildApi"; //$NON-NLS-1$ - static final String ATTR_BUILD_API = "buildApi"; //$NON-NLS-1$ - static final String ATTR_REVISION = "revision"; //$NON-NLS-1$ - static final String ATTR_MIN_API_LEVEL = "minApiLevel"; //$NON-NLS-1$ - static final String ATTR_PACKAGE_NAME = "packageName"; //$NON-NLS-1$ - static final String ATTR_APP_TITLE = "appTitle"; //$NON-NLS-1$ - static final String CATEGORY_PROJECTS = "projects"; //$NON-NLS-1$ - static final String CATEGORY_ACTIVITIES = "activities"; //$NON-NLS-1$ - static final String CATEGORY_OTHER = "other"; //$NON-NLS-1$ - static final String ATTR_APP_COMPAT = "appCompat"; //$NON-NLS-1$ - /** - * Reserved file name for the launcher icon, resolves to the xhdpi version - * - * @see CreateAssetSetWizardState#getImage - */ - public static final String DEFAULT_LAUNCHER_ICON = "launcher_icon"; //$NON-NLS-1$ - - private NewProjectPage mMainPage; - private ProjectContentsPage mContentsPage; - private ActivityPage mActivityPage; - private NewTemplatePage mTemplatePage; - private NewProjectWizardState mValues; - /** The project being created */ - private IProject mProject; - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - super.init(workbench, selection); - - setWindowTitle("New Android Application"); - - mValues = new NewProjectWizardState(); - mMainPage = new NewProjectPage(mValues); - mContentsPage = new ProjectContentsPage(mValues); - mContentsPage.init(selection, AdtUtils.getActivePart()); - mActivityPage = new ActivityPage(mValues, true, true); - mActivityPage.setLauncherActivitiesOnly(true); - } - - @Override - public void addPages() { - super.addPages(); - addPage(mMainPage); - addPage(mContentsPage); - addPage(mActivityPage); - } - - @Override - public IWizardPage getNextPage(IWizardPage page) { - if (page == mMainPage) { - return mContentsPage; - } - - if (page == mContentsPage) { - if (mValues.createIcon) { - // Bundle asset studio wizard to create the launcher icon - CreateAssetSetWizardState iconState = mValues.iconState; - iconState.type = AssetType.LAUNCHER; - iconState.outputName = "ic_launcher"; //$NON-NLS-1$ - iconState.background = new RGB(0xff, 0xff, 0xff); - iconState.foreground = new RGB(0x33, 0xb6, 0xea); - iconState.trim = true; - - // ADT 20: White icon with blue shape - //iconState.shape = GraphicGenerator.Shape.CIRCLE; - //iconState.sourceType = CreateAssetSetWizardState.SourceType.CLIPART; - //iconState.clipartName = "user.png"; //$NON-NLS-1$ - //iconState.padding = 10; - - // ADT 21: Use the platform packaging icon, but allow user to customize it - iconState.sourceType = CreateAssetSetWizardState.SourceType.IMAGE; - iconState.imagePath = new File(DEFAULT_LAUNCHER_ICON); - iconState.shape = GraphicGenerator.Shape.NONE; - iconState.padding = 0; - - WizardPage p = getIconPage(mValues.iconState); - p.setTitle("Configure Launcher Icon"); - return p; - } else { - if (mValues.createActivity) { - return mActivityPage; - } else { - return null; - } - } - } - - if (page == mIconPage) { - return mActivityPage; - } - - if (page == mActivityPage && mValues.createActivity) { - if (mTemplatePage == null) { - NewTemplateWizardState activityValues = mValues.activityValues; - - // Initialize the *default* activity name based on what we've derived - // from the project name - activityValues.defaults.put("activityName", mValues.activityName); - - // Hide those parameters that the template requires but that we don't want to - // ask the users about, since we will supply these values from the rest - // of the new project wizard. - Set<String> hidden = activityValues.hidden; - hidden.add(ATTR_PACKAGE_NAME); - hidden.add(ATTR_APP_TITLE); - hidden.add(ATTR_MIN_API); - hidden.add(ATTR_MIN_API_LEVEL); - hidden.add(ATTR_TARGET_API); - hidden.add(ATTR_BUILD_API); - hidden.add(IS_LAUNCHER); - // Don't ask about hierarchical parent activities in new projects where there - // can't possibly be any - hidden.add(PARENT_ACTIVITY_CLASS); - hidden.add(ACTIVITY_TITLE); // Not used for the first activity in the project - - mTemplatePage = new NewTemplatePage(activityValues, false); - addPage(mTemplatePage); - } - mTemplatePage.setCustomMinSdk(mValues.minSdkLevel, mValues.getBuildApi()); - return mTemplatePage; - } - - if (page == mTemplatePage) { - TemplateMetadata template = mValues.activityValues.getTemplateHandler().getTemplate(); - if (template != null - && !InstallDependencyPage.isInstalled(template.getDependencies())) { - return getDependencyPage(template, true); - } - } - - if (page == mTemplatePage || !mValues.createActivity && page == mActivityPage - || page == getDependencyPage(null, false)) { - return null; - } - - return super.getNextPage(page); - } - - @Override - public boolean canFinish() { - // Deal with lazy creation of some pages: these may not be in the page-list yet - // since they are constructed lazily, so consider that option here. - if (mValues.createIcon && (mIconPage == null || !mIconPage.isPageComplete())) { - return false; - } - if (mValues.createActivity && (mTemplatePage == null || !mTemplatePage.isPageComplete())) { - return false; - } - - // Override super behavior (which just calls isPageComplete() on each of the pages) - // to special case the template and icon pages since we want to skip them if - // the appropriate flags are not set. - for (IWizardPage page : getPages()) { - if (page == mTemplatePage && !mValues.createActivity) { - continue; - } - if (page == mIconPage && !mValues.createIcon) { - continue; - } - if (!page.isPageComplete()) { - return false; - } - } - - return true; - } - - @Override - @NonNull - protected IProject getProject() { - return mProject; - } - - @Override - @NonNull - protected List<String> getFilesToOpen() { - return mValues.template.getFilesToOpen(); - } - - @VisibleForTesting - NewProjectWizardState getValues() { - return mValues; - } - - @VisibleForTesting - void setValues(NewProjectWizardState values) { - mValues = values; - } - - @Override - protected List<Change> computeChanges() { - final TemplateHandler template = mValues.template; - // We'll be merging in an activity template, but don't create *~ backup files - // of the merged files (such as the manifest file) in that case. - // (NOTE: After the change from direct file manipulation to creating a list of Change - // objects, this no longer applies - but the code is kept around a little while longer - // in case we want to generate change objects that makes backups of merged files) - template.setBackupMergedFiles(false); - - // Generate basic output skeleton - Map<String, Object> paramMap = new HashMap<String, Object>(); - addProjectInfo(paramMap); - TemplateHandler.addDirectoryParameters(paramMap, getProject()); - // We don't know at this point whether the activity is going to need - // AppCompat so we just assume that it will. - if (mValues.createActivity && mValues.minSdkLevel < 14) { - paramMap.put(ATTR_APP_COMPAT, true); - getFinalizingActions().add(new Runnable() { - @Override - public void run() { - AddSupportJarAction.installAppCompatLibrary(mProject, true); - } - }); - } - - return template.render(mProject, paramMap); - } - - @Override - protected boolean performFinish(final IProgressMonitor monitor) - throws InvocationTargetException { - try { - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - String name = mValues.projectName; - mProject = root.getProject(name); - - final TemplateHandler template = mValues.template; - // We'll be merging in an activity template, but don't create *~ backup files - // of the merged files (such as the manifest file) in that case. - template.setBackupMergedFiles(false); - - ProjectPopulator projectPopulator = new ProjectPopulator() { - @Override - public void populate(IProject project) throws InvocationTargetException { - // Copy in the proguard file; templates don't provide this one. - // add the default proguard config - File libFolder = new File(AdtPlugin.getOsSdkToolsFolder(), - SdkConstants.FD_LIB); - try { - assert project == mProject; - NewProjectCreator.addLocalFile(project, - new File(libFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), - // Write ProGuard config files with the extension .pro which - // is what is used in the ProGuard documentation and samples - SdkConstants.FN_PROJECT_PROGUARD_FILE, - new NullProgressMonitor()); - } catch (Exception e) { - AdtPlugin.log(e, null); - } - - try { - mProject.refreshLocal(DEPTH_INFINITE, new NullProgressMonitor()); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - - // Render the project template - List<Change> changes = computeChanges(); - if (!changes.isEmpty()) { - monitor.beginTask("Creating project...", changes.size()); - try { - CompositeChange composite = new CompositeChange("", - changes.toArray(new Change[changes.size()])); - composite.perform(monitor); - } catch (CoreException e) { - AdtPlugin.log(e, null); - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - - if (mValues.createIcon) { // TODO: Set progress - generateIcons(mProject); - } - - // Render the embedded activity template template - if (mValues.createActivity) { - final TemplateHandler activityTemplate = - mValues.activityValues.getTemplateHandler(); - // We'll be merging in an activity template, but don't create - // *~ backup files of the merged files (such as the manifest file) - // in that case. - activityTemplate.setBackupMergedFiles(false); - generateActivity(template, project, monitor); - } - } - }; - - NewProjectCreator.create(monitor, mProject, mValues.target, projectPopulator, - mValues.isLibrary, mValues.projectLocation, mValues.workingSets); - - // For new projects, ensure that we're actually using the preferred compliance, - // not just the default one - IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); - if (javaProject != null) { - ProjectHelper.enforcePreferredCompilerCompliance(javaProject); - } - - try { - mProject.refreshLocal(DEPTH_INFINITE, new NullProgressMonitor()); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - - List<Runnable> finalizingTasks = getFinalizingActions(); - for (Runnable r : finalizingTasks) { - r.run(); - } - - return true; - } catch (Exception ioe) { - AdtPlugin.log(ioe, null); - return false; - } - } - - /** - * Generate custom icons into the project based on the asset studio wizard state - */ - private void generateIcons(final IProject newProject) { - // Generate the custom icons - assert mValues.createIcon; - ConfigureAssetSetPage.generateIcons(newProject, mValues.iconState, false, mIconPage); - } - - /** - * Generate the activity: Pre-populate information about the project the - * activity needs but that we don't need to ask about when creating a new - * project - */ - private void generateActivity(TemplateHandler projectTemplate, IProject project, - IProgressMonitor monitor) throws InvocationTargetException { - assert mValues.createActivity; - NewTemplateWizardState activityValues = mValues.activityValues; - Map<String, Object> parameters = activityValues.parameters; - - addProjectInfo(parameters); - - parameters.put(IS_NEW_PROJECT, true); - parameters.put(IS_LIBRARY_PROJECT, mValues.isLibrary); - // Ensure that activities created as part of a new project are marked as - // launcher activities - parameters.put(IS_LAUNCHER, true); - TemplateHandler.addDirectoryParameters(parameters, project); - - TemplateHandler activityTemplate = activityValues.getTemplateHandler(); - activityTemplate.setBackupMergedFiles(false); - List<Change> changes = activityTemplate.render(project, parameters); - if (!changes.isEmpty()) { - monitor.beginTask("Creating template...", changes.size()); - try { - CompositeChange composite = new CompositeChange("", - changes.toArray(new Change[changes.size()])); - composite.perform(monitor); - } catch (CoreException e) { - AdtPlugin.log(e, null); - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - - List<String> filesToOpen = activityTemplate.getFilesToOpen(); - projectTemplate.getFilesToOpen().addAll(filesToOpen); - - List<Runnable> finalizingActions = activityTemplate.getFinalizingActions(); - projectTemplate.getFinalizingActions().addAll(finalizingActions); - } - - private void addProjectInfo(Map<String, Object> parameters) { - parameters.put(ATTR_PACKAGE_NAME, mValues.packageName); - parameters.put(ATTR_APP_TITLE, mValues.applicationName); - parameters.put(ATTR_MIN_API, mValues.minSdk); - parameters.put(ATTR_MIN_API_LEVEL, mValues.minSdkLevel); - parameters.put(ATTR_TARGET_API, mValues.targetSdkLevel); - parameters.put(ATTR_BUILD_API, mValues.target.getVersion().getApiLevel()); - parameters.put(ATTR_COPY_ICONS, !mValues.createIcon); - parameters.putAll(mValues.parameters); - } - - @Override - @NonNull - protected List<Runnable> getFinalizingActions() { - return mValues.template.getFinalizingActions(); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizardState.java deleted file mode 100644 index 9cd3a6dcf..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizardState.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.CATEGORY_PROJECTS; - -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; -import com.android.sdklib.IAndroidTarget; - -import org.eclipse.ui.IWorkingSet; - -import java.util.HashMap; -import java.util.Map; - -/** - * Value object which holds the current state of the wizard pages for the - * {@link NewProjectWizard} - */ -public class NewProjectWizardState { - /** Creates a new {@link NewProjectWizardState} */ - public NewProjectWizardState() { - template = TemplateHandler.createFromName(CATEGORY_PROJECTS, - "NewAndroidApplication"); //$NON-NLS-1$ - } - - /** The template handler instantiating the project */ - public final TemplateHandler template; - - /** The name of the project */ - public String projectName; - - /** The derived name of the activity, if any */ - public String activityName; - - /** The derived title of the activity, if any */ - public String activityTitle; - - /** The application name */ - public String applicationName; - - /** The package name */ - public String packageName; - - /** Whether the project name has been edited by the user */ - public boolean projectModified; - - /** Whether the package name has been edited by the user */ - public boolean packageModified; - - /** Whether the activity name has been edited by the user */ - public boolean activityNameModified; - - /** Whether the activity title has been edited by the user */ - public boolean activityTitleModified; - - /** Whether the application name has been edited by the user */ - public boolean applicationModified; - - /** The compilation target to use for this project */ - public IAndroidTarget target; - - /** The minimum SDK API level, as a string (if the API is a preview release with a codename) */ - public String minSdk; - - /** The minimum SDK API level to use */ - public int minSdkLevel; - - /** The target SDK level */ - public int targetSdkLevel = AdtUtils.getHighestKnownApiLevel(); - - /** Whether this project should be marked as a library project */ - public boolean isLibrary; - - /** Whether to create an activity (if so, the activity state is stored in - * {@link #activityValues}) */ - public boolean createActivity = true; - - /** Whether a custom icon should be created instead of just reusing the default (if so, - * the icon wizard state is stored in {@link #iconState}) */ - public boolean createIcon = true; - - // Delegated wizards - - /** State for the asset studio wizard, used to create custom icons */ - public CreateAssetSetWizardState iconState = new CreateAssetSetWizardState(); - - /** State for the template wizard, used to embed an activity template */ - public NewTemplateWizardState activityValues = new NewTemplateWizardState(); - - /** Whether a custom location should be used */ - public boolean useDefaultLocation = true; - - /** Folder where the project should be created. */ - public String projectLocation; - - /** Configured parameters, by id */ - public final Map<String, Object> parameters = new HashMap<String, Object>(); - - /** The set of chosen working sets to use when creating the project */ - public IWorkingSet[] workingSets = new IWorkingSet[0]; - - /** - * Returns the build target API level - * - * @return the build target API level - */ - public int getBuildApi() { - return target != null ? target.getVersion().getApiLevel() : minSdkLevel; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java deleted file mode 100644 index 57cf5c824..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java +++ /dev/null @@ -1,946 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.SdkConstants.CLASS_ACTIVITY; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_BUILD_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_DEFAULT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_ID; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_PADDING; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.PREVIEW_WIDTH; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageControl; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; -import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.ProjectCombo; -import com.android.ide.eclipse.adt.internal.wizards.templates.Parameter.Constraint; -import com.android.ide.eclipse.adt.internal.wizards.templates.Parameter.Type; -import com.android.tools.lint.detector.api.LintUtils; -import com.google.common.collect.Lists; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.core.Flags; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeHierarchy; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; -import org.eclipse.jdt.ui.IJavaElementSearchConstants; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension; -import org.eclipse.jdt.ui.dialogs.ITypeInfoRequestor; -import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.fieldassist.ControlDecoration; -import org.eclipse.jface.fieldassist.FieldDecoration; -import org.eclipse.jface.fieldassist.FieldDecorationRegistry; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.dialogs.SelectionDialog; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.io.ByteArrayInputStream; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * First wizard page in the "New Project From Template" wizard (which is parameterized - * via template.xml files) - */ -public class NewTemplatePage extends WizardPage - implements ModifyListener, SelectionListener, FocusListener { - /** The default width to use for the wizard page */ - static final int WIZARD_PAGE_WIDTH = 600; - - private final NewTemplateWizardState mValues; - private final boolean mChooseProject; - private int mCustomMinSdk = -1; - private int mCustomBuildApi = -1; - private boolean mIgnore; - private boolean mShown; - private Control mFirst; - // TODO: Move decorators to the Parameter objects? - private Map<String, ControlDecoration> mDecorations = new HashMap<String, ControlDecoration>(); - private Label mHelpIcon; - private Label mTipLabel; - private ImageControl mPreview; - private Image mPreviewImage; - private boolean mDisposePreviewImage; - private ProjectCombo mProjectButton; - private StringEvaluator mEvaluator; - - private TemplateMetadata mShowingTemplate; - - /** - * Creates a new {@link NewTemplatePage} - * - * @param values the wizard state - * @param chooseProject whether the wizard should present a project chooser, - * and update {@code values}' project field - */ - NewTemplatePage(NewTemplateWizardState values, boolean chooseProject) { - super("newTemplatePage"); //$NON-NLS-1$ - mValues = values; - mChooseProject = chooseProject; - } - - /** - * @param minSdk a minimum SDK to use, provided chooseProject is false. If - * it is true, then the minimum SDK used for validation will be - * the one of the project - * @param buildApi the build API to use - */ - void setCustomMinSdk(int minSdk, int buildApi) { - assert !mChooseProject; - //assert buildApi >= minSdk; - mCustomMinSdk = minSdk; - mCustomBuildApi = buildApi; - } - - @Override - public void createControl(Composite parent2) { - Composite parent = new Composite(parent2, SWT.NULL); - setControl(parent); - GridLayout parentLayout = new GridLayout(3, false); - parentLayout.verticalSpacing = 0; - parentLayout.marginWidth = 0; - parentLayout.marginHeight = 0; - parentLayout.horizontalSpacing = 0; - parent.setLayout(parentLayout); - - // Reserve enough width (since the panel is created lazily later) - Label label = new Label(parent, SWT.NONE); - GridData data = new GridData(); - data.widthHint = WIZARD_PAGE_WIDTH; - label.setLayoutData(data); - } - - @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused - private void onEnter() { - TemplateMetadata template = mValues.getTemplateHandler().getTemplate(); - if (template == mShowingTemplate) { - return; - } - mShowingTemplate = template; - - Composite parent = (Composite) getControl(); - - Control[] children = parent.getChildren(); - if (children.length > 0) { - for (Control c : parent.getChildren()) { - c.dispose(); - } - for (ControlDecoration decoration : mDecorations.values()) { - decoration.dispose(); - } - mDecorations.clear(); - } - - Composite container = new Composite(parent, SWT.NULL); - container.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - GridLayout gl_container = new GridLayout(3, false); - gl_container.horizontalSpacing = 10; - container.setLayout(gl_container); - - if (mChooseProject) { - // Project: [button] - String tooltip = "The Android Project where the new resource will be created."; - Label projectLabel = new Label(container, SWT.NONE); - projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - projectLabel.setText("Project:"); - projectLabel.setToolTipText(tooltip); - - ProjectChooserHelper helper = - new ProjectChooserHelper(getShell(), null /* filter */); - mProjectButton = new ProjectCombo(helper, container, mValues.project); - mProjectButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - mProjectButton.setToolTipText(tooltip); - mProjectButton.addSelectionListener(this); - - //Label projectSeparator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL); - //projectSeparator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); - } - - // Add parameters - mFirst = null; - String thumb = null; - if (template != null) { - thumb = template.getThumbnailPath(); - String title = template.getTitle(); - if (title != null && !title.isEmpty()) { - setTitle(title); - } - String description = template.getDescription(); - if (description != null && !description.isEmpty()) { - setDescription(description); - } - - Map<String, String> defaults = mValues.defaults; - Set<String> seen = null; - if (LintUtils.assertionsEnabled()) { - seen = new HashSet<String>(); - } - - List<Parameter> parameters = template.getParameters(); - for (Parameter parameter : parameters) { - Parameter.Type type = parameter.type; - - if (type == Parameter.Type.SEPARATOR) { - Label separator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL); - separator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); - continue; - } - - String id = parameter.id; - assert id != null && !id.isEmpty() : ATTR_ID; - Object value = defaults.get(id); - if (value == null) { - value = parameter.value; - } - - String name = parameter.name; - String help = parameter.help; - - // Required - assert name != null && !name.isEmpty() : ATTR_NAME; - // Ensure id's are unique: - assert seen != null && seen.add(id) : id; - - // Skip attributes that were already provided by the surrounding - // context. For example, when adding into an existing project, - // provide the minimum SDK automatically from the project. - if (mValues.hidden != null && mValues.hidden.contains(id)) { - continue; - } - - switch (type) { - case STRING: { - // TODO: Look at the constraints to add validators here - // TODO: If I type.equals("layout") add resource validator for layout - // names - // TODO: If I type.equals("class") make class validator - - // TODO: Handle package and id better later - Label label = new Label(container, SWT.NONE); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, - 1, 1)); - label.setText(name); - - Text text = new Text(container, SWT.BORDER); - text.setData(parameter); - parameter.control = text; - - if (parameter.constraints.contains(Constraint.EXISTS)) { - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, - 1, 1)); - - Button button = new Button(container, SWT.FLAT); - button.setData(parameter); - button.setText("..."); - button.addSelectionListener(this); - } else { - text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, - 2, 1)); - } - - boolean hasValue = false; - if (value instanceof String) { - String stringValue = (String) value; - hasValue = !stringValue.isEmpty(); - text.setText(stringValue); - mValues.parameters.put(id, value); - } - - if (!hasValue) { - if (parameter.constraints.contains(Constraint.EMPTY)) { - text.setMessage("Optional"); - } else if (parameter.constraints.contains(Constraint.NONEMPTY)) { - text.setMessage("Required"); - } - } - - text.addModifyListener(this); - text.addFocusListener(this); - - if (mFirst == null) { - mFirst = text; - } - - if (help != null && !help.isEmpty()) { - text.setToolTipText(help); - ControlDecoration decoration = createFieldDecoration(id, text, help); - } - break; - } - case BOOLEAN: { - Label label = new Label(container, SWT.NONE); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, - 1, 1)); - - Button checkBox = new Button(container, SWT.CHECK); - checkBox.setText(name); - checkBox.setData(parameter); - parameter.control = checkBox; - checkBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, - 2, 1)); - - if (value instanceof Boolean) { - Boolean selected = (Boolean) value; - checkBox.setSelection(selected); - mValues.parameters.put(id, value); - } - - checkBox.addSelectionListener(this); - checkBox.addFocusListener(this); - - if (mFirst == null) { - mFirst = checkBox; - } - - if (help != null && !help.isEmpty()) { - checkBox.setToolTipText(help); - ControlDecoration decoration = createFieldDecoration(id, checkBox, - help); - } - break; - } - case ENUM: { - Label label = new Label(container, SWT.NONE); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, - 1, 1)); - label.setText(name); - - Combo combo = createOptionCombo(parameter, container, mValues.parameters, - this, this); - combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, - 2, 1)); - - if (mFirst == null) { - mFirst = combo; - } - - if (help != null && !help.isEmpty()) { - ControlDecoration decoration = createFieldDecoration(id, combo, help); - } - break; - } - case SEPARATOR: - // Already handled above - assert false : type; - break; - default: - assert false : type; - } - } - } - - // Preview - mPreview = new ImageControl(parent, SWT.NONE, null); - mPreview.setDisposeImage(false); // Handled manually in this class - GridData gd_mImage = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1); - gd_mImage.widthHint = PREVIEW_WIDTH + 2 * PREVIEW_PADDING; - mPreview.setLayoutData(gd_mImage); - - Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - GridData separatorData = new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1); - separatorData.heightHint = 16; - separator.setLayoutData(separatorData); - - // Generic help - mHelpIcon = new Label(parent, SWT.NONE); - mHelpIcon.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1)); - Image icon = IconFactory.getInstance().getIcon("quickfix"); - mHelpIcon.setImage(icon); - mHelpIcon.setVisible(false); - mTipLabel = new Label(parent, SWT.WRAP); - mTipLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - - setPreview(thumb); - - parent.layout(true, true); - // TODO: This is a workaround for the fact that (at least on OSX) you end up - // with some visual artifacts from the control decorations in the upper left corner - // (outside the parent widget itself) from the initial control decoration placement - // prior to layout. Therefore, perform a redraw. A better solution would be to - // delay creation of the control decorations until layout has been performed. - // Let's do that soon. - parent.getParent().redraw(); - } - - @NonNull - static Combo createOptionCombo( - @NonNull Parameter parameter, - @NonNull Composite container, - @NonNull Map<String, Object> valueMap, - @NonNull SelectionListener selectionListener, - @NonNull FocusListener focusListener) { - Combo combo = new Combo(container, SWT.READ_ONLY); - - List<Element> options = parameter.getOptions(); - assert options.size() > 0; - int selected = 0; - List<String> ids = Lists.newArrayList(); - List<Integer> minSdks = Lists.newArrayList(); - List<Integer> minBuildApis = Lists.newArrayList(); - List<String> labels = Lists.newArrayList(); - for (int i = 0, n = options.size(); i < n; i++) { - Element option = options.get(i); - String optionId = option.getAttribute(ATTR_ID); - assert optionId != null && !optionId.isEmpty() : ATTR_ID; - String isDefault = option.getAttribute(ATTR_DEFAULT); - if (isDefault != null && !isDefault.isEmpty() && - Boolean.valueOf(isDefault)) { - selected = i; - } - NodeList childNodes = option.getChildNodes(); - assert childNodes.getLength() == 1 && - childNodes.item(0).getNodeType() == Node.TEXT_NODE; - String optionLabel = childNodes.item(0).getNodeValue().trim(); - - String minApiString = option.getAttribute(ATTR_MIN_API); - int minSdk = 1; - if (minApiString != null && !minApiString.isEmpty()) { - try { - minSdk = Integer.parseInt(minApiString); - } catch (NumberFormatException nufe) { - // Templates aren't allowed to contain codenames, should - // always be an integer - AdtPlugin.log(nufe, null); - minSdk = 1; - } - } - String minBuildApiString = option.getAttribute(ATTR_MIN_BUILD_API); - int minBuildApi = 1; - if (minBuildApiString != null && !minBuildApiString.isEmpty()) { - try { - minBuildApi = Integer.parseInt(minBuildApiString); - } catch (NumberFormatException nufe) { - // Templates aren't allowed to contain codenames, should - // always be an integer - AdtPlugin.log(nufe, null); - minBuildApi = 1; - } - } - minSdks.add(minSdk); - minBuildApis.add(minBuildApi); - ids.add(optionId); - labels.add(optionLabel); - } - combo.setData(parameter); - parameter.control = combo; - combo.setData(ATTR_ID, ids.toArray(new String[ids.size()])); - combo.setData(ATTR_MIN_API, minSdks.toArray(new Integer[minSdks.size()])); - combo.setData(ATTR_MIN_BUILD_API, minBuildApis.toArray( - new Integer[minBuildApis.size()])); - assert labels.size() > 0; - combo.setItems(labels.toArray(new String[labels.size()])); - combo.select(selected); - - combo.addSelectionListener(selectionListener); - combo.addFocusListener(focusListener); - - valueMap.put(parameter.id, ids.get(selected)); - - if (parameter.help != null && !parameter.help.isEmpty()) { - combo.setToolTipText(parameter.help); - } - - return combo; - } - - private void setPreview(String thumb) { - Image oldImage = mPreviewImage; - boolean dispose = mDisposePreviewImage; - mPreviewImage = null; - - if (thumb == null || thumb.isEmpty()) { - mPreviewImage = TemplateMetadata.getDefaultTemplateIcon(); - mDisposePreviewImage = false; - } else { - byte[] data = mValues.getTemplateHandler().readTemplateResource(thumb); - if (data != null) { - try { - mPreviewImage = new Image(getControl().getDisplay(), - new ByteArrayInputStream(data)); - mDisposePreviewImage = true; - } catch (Exception e) { - AdtPlugin.log(e, null); - } - } - if (mPreviewImage == null) { - return; - } - } - - mPreview.setImage(mPreviewImage); - mPreview.fitToWidth(PREVIEW_WIDTH); - - if (oldImage != null && dispose) { - oldImage.dispose(); - } - } - - @Override - public void dispose() { - super.dispose(); - - if (mPreviewImage != null && mDisposePreviewImage) { - mDisposePreviewImage = false; - mPreviewImage.dispose(); - mPreviewImage = null; - } - } - - private ControlDecoration createFieldDecoration(String id, Control control, - String description) { - ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT); - decoration.setMarginWidth(2); - FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault(). - getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION); - decoration.setImage(errorFieldIndicator.getImage()); - decoration.setDescriptionText(description); - control.setToolTipText(description); - mDecorations.put(id, decoration); - - return decoration; - } - - @Override - public boolean isPageComplete() { - // Force user to reach this page before hitting Finish - return mShown && super.isPageComplete(); - } - - @Override - public void setVisible(boolean visible) { - if (visible) { - onEnter(); - } - - super.setVisible(visible); - - if (mFirst != null) { - mFirst.setFocus(); - } - - if (visible) { - mShown = true; - } - - validatePage(); - } - - /** Returns the parameter associated with the given control */ - @Nullable - static Parameter getParameter(Control control) { - return (Parameter) control.getData(); - } - - /** - * Returns the current string evaluator, if any - * - * @return the evaluator or null - */ - @Nullable - public StringEvaluator getEvaluator() { - return mEvaluator; - } - - // ---- Validation ---- - - private void validatePage() { - int minSdk = getMinSdk(); - int buildApi = getBuildApi(); - IStatus status = mValues.getTemplateHandler().validateTemplate(minSdk, buildApi); - - if (status == null || status.isOK()) { - if (mChooseProject && mValues.project == null) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Please select an Android project."); - } - } - - for (Parameter parameter : mShowingTemplate.getParameters()) { - if (parameter.type == Parameter.Type.SEPARATOR) { - continue; - } - IInputValidator validator = parameter.getValidator(mValues.project); - if (validator != null) { - ControlDecoration decoration = mDecorations.get(parameter.id); - String value = parameter.value == null ? "" : parameter.value.toString(); - String error = validator.isValid(value); - if (error != null) { - IStatus s = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, error); - if (decoration != null) { - updateDecorator(decoration, s, parameter.help); - } - if (status == null || status.isOK()) { - status = s; - } - } else if (decoration != null) { - updateDecorator(decoration, null, parameter.help); - } - } - - if (status == null || status.isOK()) { - if (parameter.control instanceof Combo) { - status = validateCombo(status, parameter, minSdk, buildApi); - } - } - } - - setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); - if (status != null) { - setMessage(status.getMessage(), - status.getSeverity() == IStatus.ERROR - ? IMessageProvider.ERROR : IMessageProvider.WARNING); - } else { - setErrorMessage(null); - setMessage(null); - } - } - - /** Validates the given combo */ - static IStatus validateCombo(IStatus status, Parameter parameter, int minSdk, int buildApi) { - Combo combo = (Combo) parameter.control; - int index = combo.getSelectionIndex(); - return validateCombo(status, parameter, index, minSdk, buildApi); - } - - /** Validates the given combo assuming the value at the given index is chosen */ - static IStatus validateCombo(IStatus status, Parameter parameter, int index, - int minSdk, int buildApi) { - Combo combo = (Combo) parameter.control; - Integer[] optionIds = (Integer[]) combo.getData(ATTR_MIN_API); - // Check minSdk - if (index != -1 && index < optionIds.length) { - Integer requiredMinSdk = optionIds[index]; - if (requiredMinSdk > minSdk) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format( - "%1$s \"%2$s\" requires a minimum SDK version of at " + - "least %3$d, and the current min version is %4$d", - parameter.name, combo.getItems()[index], requiredMinSdk, minSdk)); - } - } - - // Check minimum build target - optionIds = (Integer[]) combo.getData(ATTR_MIN_BUILD_API); - if (index != -1 && index < optionIds.length) { - Integer requiredBuildApi = optionIds[index]; - if (requiredBuildApi > buildApi) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format( - "%1$s \"%2$s\" requires a build target API version of at " + - "least %3$d, and the current version is %4$d", - parameter.name, combo.getItems()[index], requiredBuildApi, buildApi)); - } - } - return status; - } - - private int getMinSdk() { - return mChooseProject ? mValues.getMinSdk() : mCustomMinSdk; - } - - private int getBuildApi() { - return mChooseProject ? mValues.getBuildApi() : mCustomBuildApi; - } - - private void updateDecorator(ControlDecoration decorator, IStatus status, String help) { - if (help != null && !help.isEmpty()) { - decorator.setDescriptionText(status != null ? status.getMessage() : help); - - int severity = status != null ? status.getSeverity() : IStatus.OK; - String id; - if (severity == IStatus.ERROR) { - id = FieldDecorationRegistry.DEC_ERROR; - } else if (severity == IStatus.WARNING) { - id = FieldDecorationRegistry.DEC_WARNING; - } else { - id = FieldDecorationRegistry.DEC_INFORMATION; - } - FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault(). - getFieldDecoration(id); - decorator.setImage(errorFieldIndicator.getImage()); - } else { - if (status == null || status.isOK()) { - decorator.hide(); - } else { - decorator.show(); - } - } - } - - // ---- Implements ModifyListener ---- - - @Override - public void modifyText(ModifyEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source instanceof Text) { - Text text = (Text) source; - editParameter(text, text.getText().trim()); - } - - validatePage(); - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mProjectButton) { - mValues.project = mProjectButton.getSelectedProject(); - } else if (source instanceof Combo) { - Combo combo = (Combo) source; - String[] optionIds = (String[]) combo.getData(ATTR_ID); - int index = combo.getSelectionIndex(); - if (index != -1 && index < optionIds.length) { - String optionId = optionIds[index]; - editParameter(combo, optionId); - TemplateMetadata template = mValues.getTemplateHandler().getTemplate(); - if (template != null) { - setPreview(template.getThumbnailPath()); - } - } - } else if (source instanceof Button) { - Button button = (Button) source; - Parameter parameter = (Parameter) button.getData(); - if (parameter.type == Type.BOOLEAN) { - // Checkbox parameter - editParameter(button, button.getSelection()); - - TemplateMetadata template = mValues.getTemplateHandler().getTemplate(); - if (template != null) { - setPreview(template.getThumbnailPath()); - } - } else { - // Choose button for some other parameter, usually a text - String activity = chooseActivity(); - if (activity != null) { - setValue(parameter, activity); - } - } - } - - validatePage(); - } - - private String chooseActivity() { - try { - // Compute a search scope: We need to merge all the subclasses - // android.app.Fragment and android.support.v4.app.Fragment - IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); - IProject project = mValues.project; - IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - IType activityType = null; - - if (javaProject != null) { - activityType = javaProject.findType(CLASS_ACTIVITY); - } - if (activityType == null) { - IJavaProject[] projects = BaseProjectHelper.getAndroidProjects(null); - for (IJavaProject p : projects) { - activityType = p.findType(CLASS_ACTIVITY); - if (activityType != null) { - break; - } - } - } - if (activityType != null) { - NullProgressMonitor monitor = new NullProgressMonitor(); - ITypeHierarchy hierarchy = activityType.newTypeHierarchy(monitor); - IType[] classes = hierarchy.getAllSubtypes(activityType); - scope = SearchEngine.createJavaSearchScope(classes, IJavaSearchScope.SOURCES); - } - - Shell parent = AdtPlugin.getShell(); - final SelectionDialog dialog = JavaUI.createTypeDialog( - parent, - new ProgressMonitorDialog(parent), - scope, - IJavaElementSearchConstants.CONSIDER_CLASSES, false, - // Use ? as a default filter to fill dialog with matches - "?", //$NON-NLS-1$ - new TypeSelectionExtension() { - @Override - public ITypeInfoFilterExtension getFilterExtension() { - return new ITypeInfoFilterExtension() { - @Override - public boolean select(ITypeInfoRequestor typeInfoRequestor) { - int modifiers = typeInfoRequestor.getModifiers(); - if (!Flags.isPublic(modifiers) - || Flags.isInterface(modifiers) - || Flags.isEnum(modifiers)) { - return false; - } - return true; - } - }; - } - }); - - dialog.setTitle("Choose Activity Class"); - dialog.setMessage("Select an Activity class (? = any character, * = any string):"); - if (dialog.open() == IDialogConstants.CANCEL_ID) { - return null; - } - - Object[] types = dialog.getResult(); - if (types != null && types.length > 0) { - return ((IType) types[0]).getFullyQualifiedName(); - } - } catch (JavaModelException e) { - AdtPlugin.log(e, null); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - return null; - } - - private void editParameter(Control control, Object value) { - Parameter parameter = getParameter(control); - if (parameter != null) { - String id = parameter.id; - parameter.value = value; - parameter.edited = value != null && !value.toString().isEmpty(); - mValues.parameters.put(id, value); - - // Update dependent variables, if any - List<Parameter> parameters = mShowingTemplate.getParameters(); - for (Parameter p : parameters) { - if (p == parameter || p.suggest == null || p.edited || - p.type == Parameter.Type.SEPARATOR) { - continue; - } - if (!p.suggest.contains(id)) { - continue; - } - - try { - if (mEvaluator == null) { - mEvaluator = new StringEvaluator(); - } - String updated = mEvaluator.evaluate(p.suggest, parameters); - if (updated != null && !updated.equals(p.value)) { - setValue(p, updated); - } - } catch (Throwable t) { - // Pass: Ignore updating if something wrong happens - t.printStackTrace(); // during development only - } - } - } - } - - private void setValue(Parameter p, String value) { - p.value = value; - mValues.parameters.put(p.id, value); - - // Update form widgets - boolean prevIgnore = mIgnore; - try { - mIgnore = true; - if (p.control instanceof Text) { - ((Text) p.control).setText(value); - } else if (p.control instanceof Button) { - // TODO: Handle - } else if (p.control instanceof Combo) { - // TODO: Handle - } else if (p.control != null) { - assert false : p.control; - } - } finally { - mIgnore = prevIgnore; - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - // ---- Implements FocusListener ---- - - @Override - public void focusGained(FocusEvent e) { - Object source = e.getSource(); - String tip = ""; - - if (source instanceof Control) { - Control control = (Control) source; - Parameter parameter = getParameter(control); - if (parameter != null) { - ControlDecoration decoration = mDecorations.get(parameter.id); - if (decoration != null) { - tip = decoration.getDescriptionText(); - } - } - } - - mTipLabel.setText(tip); - mHelpIcon.setVisible(tip.length() > 0); - } - - @Override - public void focusLost(FocusEvent e) { - mTipLabel.setText(""); - mHelpIcon.setVisible(false); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java deleted file mode 100644 index 99814f731..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_BUILD_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API_LEVEL; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_TARGET_API; - -import com.android.annotations.NonNull; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; - -import java.io.File; -import java.util.List; -import java.util.Set; - -/** - * Template wizard which creates parameterized templates - */ -public class NewTemplateWizard extends TemplateWizard { - /** Template name and location under $sdk/templates for the default activity */ - static final String BLANK_ACTIVITY = "activities/BlankActivity"; //$NON-NLS-1$ - /** Template name and location under $sdk/templates for the custom view template */ - static final String CUSTOM_VIEW = "other/CustomView"; //$NON-NLS-1$ - - protected NewTemplatePage mMainPage; - protected NewTemplateWizardState mValues; - private final String mTemplateName; - - NewTemplateWizard(String templateName) { - mTemplateName = templateName; - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - super.init(workbench, selection); - - mValues = new NewTemplateWizardState(); - - File template = TemplateManager.getTemplateLocation(mTemplateName); - if (template != null) { - mValues.setTemplateLocation(template); - } - hideBuiltinParameters(); - - List<IProject> projects = AdtUtils.getSelectedProjects(selection); - if (projects.size() == 1) { - mValues.project = projects.get(0); - } - - mMainPage = new NewTemplatePage(mValues, true); - } - - @Override - protected boolean shouldAddIconPage() { - return mValues.getIconState() != null; - } - - /** - * Hide those parameters that the template requires but that we don't want - * to ask the users about, since we can derive it from the target project - * the template is written into. - */ - protected void hideBuiltinParameters() { - Set<String> hidden = mValues.hidden; - hidden.add(ATTR_PACKAGE_NAME); - hidden.add(ATTR_MIN_API); - hidden.add(ATTR_MIN_API_LEVEL); - hidden.add(ATTR_TARGET_API); - hidden.add(ATTR_BUILD_API); - } - - @Override - public void addPages() { - super.addPages(); - addPage(mMainPage); - } - - @Override - public IWizardPage getNextPage(IWizardPage page) { - TemplateMetadata template = mValues.getTemplateHandler().getTemplate(); - - if (page == mMainPage && shouldAddIconPage()) { - WizardPage iconPage = getIconPage(mValues.getIconState()); - mValues.updateIconState(mMainPage.getEvaluator()); - return iconPage; - } else if (page == mMainPage - || shouldAddIconPage() && page == getIconPage(mValues.getIconState())) { - if (template != null) { - if (InstallDependencyPage.isInstalled(template.getDependencies())) { - return getPreviewPage(mValues); - } else { - return getDependencyPage(template, true); - } - } - } else if (page == getDependencyPage(template, false)) { - return getPreviewPage(mValues); - } - - return super.getNextPage(page); - } - - @Override - @NonNull - protected IProject getProject() { - return mValues.project; - } - - @Override - @NonNull - protected List<String> getFilesToOpen() { - TemplateHandler activityTemplate = mValues.getTemplateHandler(); - return activityTemplate.getFilesToOpen(); - } - - @Override - @NonNull - protected List<Runnable> getFinalizingActions() { - TemplateHandler activityTemplate = mValues.getTemplateHandler(); - return activityTemplate.getFinalizingActions(); - } - - @Override - protected List<Change> computeChanges() { - return mValues.computeChanges(); - } - - /** - * Opens the given set of files (as relative paths within a given project - * - * @param project the project containing the paths - * @param relativePaths the paths to files to open - * @param mWorkbench the workbench to open the files in - */ - public static void openFiles( - @NonNull final IProject project, - @NonNull final List<String> relativePaths, - @NonNull final IWorkbench mWorkbench) { - if (!relativePaths.isEmpty()) { - // This has to be delayed in order for focus handling to work correctly - AdtPlugin.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - for (String path : relativePaths) { - IResource resource = project.findMember(path); - if (resource != null) { - if (resource instanceof IFile) { - try { - AdtPlugin.openFile((IFile) resource, null, false); - } catch (PartInitException e) { - AdtPlugin.log(e, "Failed to open %1$s", //$NON-NLS-1$ - resource.getFullPath().toString()); - } - } - boolean isLast = relativePaths.size() == 1 || - path.equals(relativePaths.get(relativePaths.size() - 1)); - if (isLast) { - BasicNewResourceWizard.selectAndReveal(resource, - mWorkbench.getActiveWorkbenchWindow()); - } - } - } - } - }); - } - } - - /** - * Specific New Custom View wizard - */ - public static class NewCustomViewWizard extends NewTemplateWizard { - /** Creates a new {@link NewCustomViewWizard} */ - public NewCustomViewWizard() { - super(CUSTOM_VIEW); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - super.init(workbench, selection); - setWindowTitle("New Custom View"); - super.mMainPage.setTitle("New Custom View"); - super.mMainPage.setDescription("Creates a new custom view"); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java deleted file mode 100644 index 2c97003f2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_BUILD_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_COPY_ICONS; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API_LEVEL; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_TARGET_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_LIBRARY_PROJECT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.IS_NEW_PROJECT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewTemplateWizard.BLANK_ACTIVITY; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.internal.assetstudio.ConfigureAssetSetPage; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.sdklib.IAndroidTarget; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.NullChange; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Value object which holds the current state of the wizard pages for the - * {@link NewTemplateWizard} - */ -public class NewTemplateWizardState { - /** Template handler responsible for instantiating templates and reading resources */ - private TemplateHandler mTemplateHandler; - - /** Configured parameters, by id */ - public final Map<String, Object> parameters = new HashMap<String, Object>(); - - /** Configured defaults for the parameters, by id */ - public final Map<String, String> defaults = new HashMap<String, String>(); - - /** Ids for parameters which should be hidden (because the client wizard already - * has information for these parameters) */ - public final Set<String> hidden = new HashSet<String>(); - - /** - * The chosen project (which may be null if the wizard page is being - * embedded in the new project wizard) - */ - public IProject project; - - /** The minimum API level to use for this template */ - public int minSdkLevel; - - /** Location of the template being created */ - private File mTemplateLocation; - - /** - * State for the asset studio wizard, used to create custom icons provided - * the icon requests it with an {@code <icons>} element - */ - private CreateAssetSetWizardState mIconState; - - /** - * Create a new state object for use by the {@link NewTemplatePage} - */ - public NewTemplateWizardState() { - parameters.put(IS_NEW_PROJECT, false); - } - - @NonNull - TemplateHandler getTemplateHandler() { - if (mTemplateHandler == null) { - File inputPath; - if (mTemplateLocation != null) { - inputPath = mTemplateLocation; - } else { - // Default - inputPath = TemplateManager.getTemplateLocation(BLANK_ACTIVITY); - } - mTemplateHandler = TemplateHandler.createFromPath(inputPath); - } - - return mTemplateHandler; - } - - /** Sets the current template */ - void setTemplateLocation(File file) { - if (!file.equals(mTemplateLocation)) { - mTemplateLocation = file; - mTemplateHandler = null; - } - } - - /** Returns the current template */ - File getTemplateLocation() { - return mTemplateLocation; - } - - /** Returns the min SDK version to use */ - int getMinSdk() { - if (project == null) { - return -1; - } - ManifestInfo manifest = ManifestInfo.get(project); - return manifest.getMinSdkVersion(); - } - - /** Returns the build API version to use */ - int getBuildApi() { - if (project == null) { - return -1; - } - IAndroidTarget target = Sdk.getCurrent().getTarget(project); - if (target != null) { - return target.getVersion().getApiLevel(); - } - - return getMinSdk(); - } - - /** Computes the changes this wizard will make */ - @NonNull - List<Change> computeChanges() { - if (project == null) { - return Collections.emptyList(); - } - - ManifestInfo manifest = ManifestInfo.get(project); - parameters.put(ATTR_PACKAGE_NAME, manifest.getPackage()); - parameters.put(ATTR_MIN_API, manifest.getMinSdkName()); - parameters.put(ATTR_MIN_API_LEVEL, manifest.getMinSdkVersion()); - parameters.put(ATTR_TARGET_API, manifest.getTargetSdkVersion()); - parameters.put(ATTR_BUILD_API, getBuildApi()); - parameters.put(ATTR_COPY_ICONS, mIconState == null); - ProjectState projectState = Sdk.getProjectState(project); - parameters.put(IS_LIBRARY_PROJECT, - projectState != null ? projectState.isLibrary() : false); - - TemplateHandler.addDirectoryParameters(parameters, project); - - List<Change> changes = getTemplateHandler().render(project, parameters); - - if (mIconState != null) { - String title = String.format("Generate icons (res/drawable-<density>/%1$s.png)", - mIconState.outputName); - changes.add(new NullChange(title) { - @Override - public Change perform(IProgressMonitor pm) throws CoreException { - ConfigureAssetSetPage.generateIcons(mIconState.project, - mIconState, false, null); - - // Not undoable: just return null instead of an undo-change. - return null; - } - }); - - } - - return changes; - } - - @NonNull - CreateAssetSetWizardState getIconState() { - if (mIconState == null) { - TemplateHandler handler = getTemplateHandler(); - if (handler != null) { - TemplateMetadata template = handler.getTemplate(); - if (template != null) { - mIconState = template.getIconState(project); - } - } - } - - return mIconState; - } - - /** - * Updates the icon state, such as the output name, based on other parameter settings - * @param evaluator the string evaluator, or null if none exists - */ - public void updateIconState(@Nullable StringEvaluator evaluator) { - TemplateMetadata template = getTemplateHandler().getTemplate(); - if (template != null) { - if (evaluator == null) { - evaluator = new StringEvaluator(); - } - template.updateIconName(template.getParameters(), evaluator); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java deleted file mode 100644 index 3139451c7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_CONSTRAINTS; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_DEFAULT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_HELP; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_ID; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SUGGEST; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator; -import com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage; -import com.android.resources.ResourceFolderType; -import com.android.resources.ResourceType; -import com.google.common.base.Splitter; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.fieldassist.ControlDecoration; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.Element; - -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Locale; - -/** - * A template parameter editable and edited by the user. - * <p> - * Note that this class encapsulates not just the metadata provided by the - * template, but the actual editing operation of that template in the wizard: it - * also captures current values, a reference to the editing widget (such that - * related widgets can be updated when one value depends on another etc) - */ -class Parameter { - enum Type { - STRING, - BOOLEAN, - ENUM, - SEPARATOR; - // TODO: Numbers? - - public static Type get(String name) { - try { - return Type.valueOf(name.toUpperCase(Locale.US)); - } catch (IllegalArgumentException e) { - AdtPlugin.printErrorToConsole("Unexpected template type '" + name + "'"); - AdtPlugin.printErrorToConsole("Expected one of :"); - for (Type s : Type.values()) { - AdtPlugin.printErrorToConsole(" " + s.name().toLowerCase(Locale.US)); - } - } - - return STRING; - } - } - - /** - * Constraints that can be applied to a parameter which helps the UI add a - * validator etc for user input. These are typically combined into a set - * of constraints via an EnumSet. - */ - enum Constraint { - /** - * This value must be unique. This constraint usually only makes sense - * when other constraints are specified, such as {@link #LAYOUT}, which - * means that the parameter should designate a name that does not - * represent an existing layout resource name - */ - UNIQUE, - - /** - * This value must already exist. This constraint usually only makes sense - * when other constraints are specified, such as {@link #LAYOUT}, which - * means that the parameter should designate a name that already exists as - * a resource name. - */ - EXISTS, - - /** The associated value must not be empty */ - NONEMPTY, - - /** The associated value is allowed to be empty */ - EMPTY, - - /** The associated value should represent a fully qualified activity class name */ - ACTIVITY, - - /** The associated value should represent an API level */ - APILEVEL, - - /** The associated value should represent a valid class name */ - CLASS, - - /** The associated value should represent a valid package name */ - PACKAGE, - - /** The associated value should represent a valid layout resource name */ - LAYOUT, - - /** The associated value should represent a valid drawable resource name */ - DRAWABLE, - - /** The associated value should represent a valid id resource name */ - ID, - - /** The associated value should represent a valid string resource name */ - STRING; - - public static Constraint get(String name) { - try { - return Constraint.valueOf(name.toUpperCase(Locale.US)); - } catch (IllegalArgumentException e) { - AdtPlugin.printErrorToConsole("Unexpected template constraint '" + name + "'"); - if (name.indexOf(',') != -1) { - AdtPlugin.printErrorToConsole("Use | to separate constraints"); - } else { - AdtPlugin.printErrorToConsole("Expected one of :"); - for (Constraint s : Constraint.values()) { - AdtPlugin.printErrorToConsole(" " + s.name().toLowerCase(Locale.US)); - } - } - } - - return NONEMPTY; - } - } - - /** The template defining the parameter */ - public final TemplateMetadata template; - - /** The type of parameter */ - @NonNull - public final Type type; - - /** The unique id of the parameter (not displayed to the user) */ - @Nullable - public final String id; - - /** The display name for this parameter */ - @Nullable - public final String name; - - /** - * The initial value for this parameter (see also {@link #suggest} for more - * dynamic defaults - */ - @Nullable - public final String initial; - - /** - * A template expression using other template parameters for producing a - * default value based on other edited parameters, if possible. - */ - @Nullable - public final String suggest; - - /** Help for the parameter, if any */ - @Nullable - public final String help; - - /** The currently edited value */ - @Nullable - public Object value; - - /** The control showing this value */ - @Nullable - public Control control; - - /** The decoration associated with the control */ - @Nullable - public ControlDecoration decoration; - - /** Whether the parameter has been edited */ - public boolean edited; - - /** The element defining this parameter */ - @NonNull - public final Element element; - - /** The constraints applicable for this parameter */ - @NonNull - public final EnumSet<Constraint> constraints; - - /** The validator, if any, for this field */ - private IInputValidator mValidator; - - /** True if this field has no validator */ - private boolean mNoValidator; - - /** Project associated with this validator */ - private IProject mValidatorProject; - - Parameter(@NonNull TemplateMetadata template, @NonNull Element parameter) { - this.template = template; - element = parameter; - - String typeName = parameter.getAttribute(TemplateHandler.ATTR_TYPE); - assert typeName != null && !typeName.isEmpty() : TemplateHandler.ATTR_TYPE; - type = Type.get(typeName); - - id = parameter.getAttribute(ATTR_ID); - initial = parameter.getAttribute(ATTR_DEFAULT); - suggest = parameter.getAttribute(ATTR_SUGGEST); - name = parameter.getAttribute(ATTR_NAME); - help = parameter.getAttribute(ATTR_HELP); - String constraintString = parameter.getAttribute(ATTR_CONSTRAINTS); - if (constraintString != null && !constraintString.isEmpty()) { - EnumSet<Constraint> constraintSet = null; - for (String s : Splitter.on('|').omitEmptyStrings().split(constraintString)) { - Constraint constraint = Constraint.get(s); - if (constraintSet == null) { - constraintSet = EnumSet.of(constraint); - } else { - constraintSet = EnumSet.copyOf(constraintSet); - constraintSet.add(constraint); - } - } - constraints = constraintSet; - } else { - constraints = EnumSet.noneOf(Constraint.class); - } - - if (initial != null && !initial.isEmpty() && type == Type.BOOLEAN) { - value = Boolean.valueOf(initial); - } else { - value = initial; - } - } - - Parameter( - @NonNull TemplateMetadata template, - @NonNull Type type, - @NonNull String id, - @NonNull String initialValue) { - this.template = template; - this.type = type; - this.id = id; - this.value = initialValue; - element = null; - initial = null; - suggest = null; - name = id; - help = null; - constraints = EnumSet.noneOf(Constraint.class); - } - - List<Element> getOptions() { - if (element != null) { - return DomUtilities.getChildren(element); - } else { - return Collections.emptyList(); - } - } - - @Nullable - public IInputValidator getValidator(@Nullable final IProject project) { - if (mNoValidator) { - return null; - } - - if (project != mValidatorProject) { - // Force update of validators if the project changes, since the validators - // are often tied to project metadata (for example, the resource name validators - // which look for name conflicts) - mValidator = null; - mValidatorProject = project; - } - - if (mValidator == null) { - if (constraints.contains(Constraint.LAYOUT)) { - if (project != null && constraints.contains(Constraint.UNIQUE)) { - mValidator = ResourceNameValidator.create(false, project, ResourceType.LAYOUT); - } else { - mValidator = ResourceNameValidator.create(false, ResourceFolderType.LAYOUT); - } - return mValidator; - } else if (constraints.contains(Constraint.STRING)) { - if (project != null && constraints.contains(Constraint.UNIQUE)) { - mValidator = ResourceNameValidator.create(false, project, ResourceType.STRING); - } else { - mValidator = ResourceNameValidator.create(false, ResourceFolderType.VALUES); - } - return mValidator; - } else if (constraints.contains(Constraint.ID)) { - if (project != null && constraints.contains(Constraint.UNIQUE)) { - mValidator = ResourceNameValidator.create(false, project, ResourceType.ID); - } else { - mValidator = ResourceNameValidator.create(false, ResourceFolderType.VALUES); - } - return mValidator; - } else if (constraints.contains(Constraint.DRAWABLE)) { - if (project != null && constraints.contains(Constraint.UNIQUE)) { - mValidator = ResourceNameValidator.create(false, project, - ResourceType.DRAWABLE); - } else { - mValidator = ResourceNameValidator.create(false, ResourceFolderType.DRAWABLE); - } - return mValidator; - } else if (constraints.contains(Constraint.PACKAGE) - || constraints.contains(Constraint.CLASS) - || constraints.contains(Constraint.ACTIVITY)) { - mValidator = new IInputValidator() { - @Override - public String isValid(String newText) { - newText = newText.trim(); - if (newText.isEmpty()) { - if (constraints.contains(Constraint.EMPTY)) { - return null; - } else if (constraints.contains(Constraint.NONEMPTY)) { - return String.format("Enter a value for %1$s", name); - } else { - // Compatibility mode: older templates might not specify; - // in that case, accept empty - if (!"activityClass".equals(id)) { //$NON-NLS-1$ - return null; - } - } - } - IStatus status; - if (constraints.contains(Constraint.ACTIVITY)) { - status = ApplicationInfoPage.validateActivity(newText); - } else if (constraints.contains(Constraint.PACKAGE)) { - status = ApplicationInfoPage.validatePackage(newText); - } else { - assert constraints.contains(Constraint.CLASS); - status = ApplicationInfoPage.validateClass(newText); - } - if (status != null && !status.isOK()) { - return status.getMessage(); - } - - // Uniqueness - if (project != null && constraints.contains(Constraint.UNIQUE)) { - try { - // Determine the package. - // If there is a package info - - IJavaProject p = BaseProjectHelper.getJavaProject(project); - if (p != null) { - String fqcn = newText; - if (fqcn.indexOf('.') == -1) { - String pkg = null; - Parameter parameter = template.getParameter( - ATTR_PACKAGE_NAME); - if (parameter != null && parameter.value != null) { - pkg = parameter.value.toString(); - } else { - pkg = ManifestInfo.get(project).getPackage(); - } - fqcn = pkg.isEmpty() ? newText : pkg + '.' + newText; - } - - IType t = p.findType(fqcn); - if (t != null && t.exists()) { - return String.format("%1$s already exists", newText); - } - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - } - - return null; - } - }; - return mValidator; - } else if (constraints.contains(Constraint.NONEMPTY)) { - mValidator = new IInputValidator() { - @Override - public String isValid(String newText) { - if (newText.trim().isEmpty()) { - return String.format("Enter a value for %1$s", name); - } - - return null; - } - }; - return mValidator; - } - - // TODO: Handle EXISTS, APILEVEL (which is currently handled manually in the - // new project wizard, and never actually input by the user in a templated - // wizard) - - mNoValidator = true; - } - - return mValidator; - } -}
\ No newline at end of file diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ProjectContentsPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ProjectContentsPage.java deleted file mode 100644 index 7d7881fcf..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ProjectContentsPage.java +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.wizards.newproject.WorkingSetGroup; -import com.android.ide.eclipse.adt.internal.wizards.newproject.WorkingSetHelper; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.DirectoryDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkingSet; - -import java.io.File; - -/** - * Second wizard page in the "New Project From Template" wizard - */ -public class ProjectContentsPage extends WizardPage - implements ModifyListener, SelectionListener, FocusListener { - - private final NewProjectWizardState mValues; - - private boolean mIgnore; - private Button mCustomIconToggle; - private Button mLibraryToggle; - - private Button mUseDefaultLocationToggle; - private Label mLocationLabel; - private Text mLocationText; - private Button mChooseLocationButton; - private static String sLastProjectLocation = System.getProperty("user.home"); //$NON-NLS-1$ - private Button mCreateActivityToggle; - private WorkingSetGroup mWorkingSetGroup; - - ProjectContentsPage(NewProjectWizardState values) { - super("newAndroidApp"); //$NON-NLS-1$ - mValues = values; - setTitle("New Android Application"); - setDescription("Configure Project"); - - mWorkingSetGroup = new WorkingSetGroup(); - setWorkingSets(new IWorkingSet[0]); - } - - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - GridLayout gl_container = new GridLayout(4, false); - gl_container.horizontalSpacing = 10; - container.setLayout(gl_container); - - mCustomIconToggle = new Button(container, SWT.CHECK); - mCustomIconToggle.setSelection(true); - mCustomIconToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - mCustomIconToggle.setText("Create custom launcher icon"); - mCustomIconToggle.setSelection(mValues.createIcon); - mCustomIconToggle.addSelectionListener(this); - - mCreateActivityToggle = new Button(container, SWT.CHECK); - mCreateActivityToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, - 4, 1)); - mCreateActivityToggle.setText("Create activity"); - mCreateActivityToggle.setSelection(mValues.createActivity); - mCreateActivityToggle.addSelectionListener(this); - - new Label(container, SWT.NONE).setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - - mLibraryToggle = new Button(container, SWT.CHECK); - mLibraryToggle.setSelection(true); - mLibraryToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - mLibraryToggle.setText("Mark this project as a library"); - mLibraryToggle.setSelection(mValues.isLibrary); - mLibraryToggle.addSelectionListener(this); - - // Blank line - new Label(container, SWT.NONE).setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - - mUseDefaultLocationToggle = new Button(container, SWT.CHECK); - mUseDefaultLocationToggle.setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - mUseDefaultLocationToggle.setText("Create Project in Workspace"); - mUseDefaultLocationToggle.addSelectionListener(this); - - mLocationLabel = new Label(container, SWT.NONE); - mLocationLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - mLocationLabel.setText("Location:"); - - mLocationText = new Text(container, SWT.BORDER); - mLocationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - mLocationText.addModifyListener(this); - - mChooseLocationButton = new Button(container, SWT.NONE); - mChooseLocationButton.setText("Browse..."); - mChooseLocationButton.addSelectionListener(this); - mChooseLocationButton.setEnabled(false); - setUseCustomLocation(!mValues.useDefaultLocation); - - new Label(container, SWT.NONE).setLayoutData( - new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); - - Composite group = mWorkingSetGroup.createControl(container); - group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 4, 1)); - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - - if (visible) { - try { - mIgnore = true; - mUseDefaultLocationToggle.setSelection(mValues.useDefaultLocation); - mLocationText.setText(mValues.projectLocation); - } finally { - mIgnore = false; - } - } - - validatePage(); - } - - private void setUseCustomLocation(boolean en) { - mValues.useDefaultLocation = !en; - mUseDefaultLocationToggle.setSelection(!en); - if (!en) { - updateProjectLocation(mValues.projectName); - } - - mLocationLabel.setEnabled(en); - mLocationText.setEnabled(en); - mChooseLocationButton.setEnabled(en); - } - - void init(IStructuredSelection selection, IWorkbenchPart activePart) { - setWorkingSets(WorkingSetHelper.getSelectedWorkingSet(selection, activePart)); - } - - /** - * Returns the working sets to which the new project should be added. - * - * @return the selected working sets to which the new project should be added - */ - private IWorkingSet[] getWorkingSets() { - return mWorkingSetGroup.getSelectedWorkingSets(); - } - - /** - * Sets the working sets to which the new project should be added. - * - * @param workingSets the initial selected working sets - */ - private void setWorkingSets(IWorkingSet[] workingSets) { - assert workingSets != null; - mWorkingSetGroup.setWorkingSets(workingSets); - } - - @Override - public IWizardPage getNextPage() { - // Sync working set data to the value object, since the WorkingSetGroup - // doesn't let us add listeners to do this lazily - mValues.workingSets = getWorkingSets(); - - return super.getNextPage(); - } - - // ---- Implements ModifyListener ---- - - @Override - public void modifyText(ModifyEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mLocationText) { - mValues.projectLocation = mLocationText.getText().trim(); - } - - validatePage(); - } - - - /** If the project should be created in the workspace, then update the project location - * based on the project name. */ - private void updateProjectLocation(String projectName) { - if (projectName == null) { - projectName = ""; - } - - boolean useDefaultLocation = mUseDefaultLocationToggle.getSelection(); - - if (useDefaultLocation) { - IPath workspace = Platform.getLocation(); - String projectLocation = workspace.append(projectName).toOSString(); - mLocationText.setText(projectLocation); - mValues.projectLocation = projectLocation; - } - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - if (mIgnore) { - return; - } - - Object source = e.getSource(); - if (source == mCustomIconToggle) { - mValues.createIcon = mCustomIconToggle.getSelection(); - } else if (source == mLibraryToggle) { - mValues.isLibrary = mLibraryToggle.getSelection(); - } else if (source == mCreateActivityToggle) { - mValues.createActivity = mCreateActivityToggle.getSelection(); - } else if (source == mUseDefaultLocationToggle) { - boolean useDefault = mUseDefaultLocationToggle.getSelection(); - setUseCustomLocation(!useDefault); - } else if (source == mChooseLocationButton) { - String dir = promptUserForLocation(getShell()); - if (dir != null) { - mLocationText.setText(dir); - mValues.projectLocation = dir; - } - } - - validatePage(); - } - - private String promptUserForLocation(Shell shell) { - DirectoryDialog dd = new DirectoryDialog(getShell()); - dd.setMessage("Select folder where project should be created"); - - String curLocation = mLocationText.getText().trim(); - if (!curLocation.isEmpty()) { - dd.setFilterPath(curLocation); - } else if (sLastProjectLocation != null) { - dd.setFilterPath(sLastProjectLocation); - } - - String dir = dd.open(); - if (dir != null) { - sLastProjectLocation = dir; - } - - return dir; - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - - // ---- Implements FocusListener ---- - - @Override - public void focusGained(FocusEvent e) { - } - - @Override - public void focusLost(FocusEvent e) { - } - - // Validation - - void validatePage() { - IStatus status = validateProjectLocation(); - - setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); - if (status != null) { - setMessage(status.getMessage(), - status.getSeverity() == IStatus.ERROR - ? IMessageProvider.ERROR : IMessageProvider.WARNING); - } else { - setErrorMessage(null); - setMessage(null); - } - } - - static IStatus validateLocationInWorkspace(NewProjectWizardState values) { - if (values.useDefaultLocation) { - return null; - } - - // Validate location - if (values.projectName != null) { - File dest = Platform.getLocation().append(values.projectName).toFile(); - if (dest.exists()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, String.format( - "There is already a file or directory named \"%1$s\" in the selected location.", - values.projectName)); - } - } - - return null; - } - - private IStatus validateProjectLocation() { - if (mValues.useDefaultLocation) { - return validateLocationInWorkspace(mValues); - } - - String location = mLocationText.getText(); - if (location.trim().isEmpty()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Provide a valid file system location where the project should be created."); - } - - File f = new File(location); - if (f.exists()) { - if (!f.isDirectory()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("'%s' is not a valid folder.", location)); - } - - File[] children = f.listFiles(); - if (children != null && children.length > 0) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("Folder '%s' is not empty.", location)); - } - } - - // if the folder doesn't exist, then make sure that the parent - // exists and is a writable folder - File parent = f.getParentFile(); - if (!parent.exists()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("Folder '%s' does not exist.", parent.getName())); - } - - if (!parent.isDirectory()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("'%s' is not a folder.", parent.getName())); - } - - if (!parent.canWrite()) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("'%s' is not writeable.", parent.getName())); - } - - return null; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/StringEvaluator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/StringEvaluator.java deleted file mode 100644 index c1c8073c0..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/StringEvaluator.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.tools.lint.detector.api.LintUtils.assertionsEnabled; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; - -import freemarker.cache.TemplateLoader; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.List; -import java.util.Map; - -/** - * A template handler which can evaluate simple strings. Used to evaluate - * parameter constraints during UI wizard value editing. - * <p> - * Unlike the more general {@link TemplateHandler} which is used to instantiate - * full template files (from resources, merging into existing files etc) this - * evaluator supports only simple strings, referencing only values from the - * provided map (and builtin functions). - */ -class StringEvaluator implements TemplateLoader { - private Map<String, Object> mParameters; - private Configuration mFreemarker; - private String mCurrentExpression; - - StringEvaluator() { - mParameters = TemplateHandler.createBuiltinMap(); - - mFreemarker = new Configuration(); - mFreemarker.setObjectWrapper(new DefaultObjectWrapper()); - mFreemarker.setTemplateLoader(this); - } - - /** Evaluates the given expression, with the given set of parameters */ - @Nullable - String evaluate(@NonNull String expression, @NonNull List<Parameter> parameters) { - // Render the instruction list template. - for (Parameter parameter : parameters) { - mParameters.put(parameter.id, parameter.value); - } - try { - mCurrentExpression = expression; - Template inputsTemplate = mFreemarker.getTemplate(expression); - StringWriter out = new StringWriter(); - inputsTemplate.process(mParameters, out); - out.flush(); - return out.toString(); - } catch (Exception e) { - if (assertionsEnabled()) { - AdtPlugin.log(e, null); - } - return null; - } - } - - // ---- Implements TemplateLoader ---- - - @Override - public Object findTemplateSource(String name) throws IOException { - return mCurrentExpression; - } - - @Override - public long getLastModified(Object templateSource) { - return 0; - } - - @Override - public Reader getReader(Object templateSource, String encoding) throws IOException { - return new StringReader(mCurrentExpression); - } - - @Override - public void closeTemplateSource(Object templateSource) throws IOException { - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java deleted file mode 100644 index 8e11841b4..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java +++ /dev/null @@ -1,1239 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.SdkConstants.ATTR_PACKAGE; -import static com.android.SdkConstants.DOT_AIDL; -import static com.android.SdkConstants.DOT_FTL; -import static com.android.SdkConstants.DOT_JAVA; -import static com.android.SdkConstants.DOT_RS; -import static com.android.SdkConstants.DOT_SVG; -import static com.android.SdkConstants.DOT_TXT; -import static com.android.SdkConstants.DOT_XML; -import static com.android.SdkConstants.EXT_XML; -import static com.android.SdkConstants.FD_NATIVE_LIBS; -import static com.android.SdkConstants.XMLNS_PREFIX; -import static com.android.ide.eclipse.adt.internal.wizards.templates.InstallDependencyPage.SUPPORT_LIBRARY_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateManager.getTemplateRootFolder; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.ide.common.xml.XmlFormatStyle; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction; -import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences; -import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback; -import com.android.manifmerger.ManifestMerger; -import com.android.manifmerger.MergerLog; -import com.android.resources.ResourceFolderType; -import com.android.utils.SdkUtils; -import com.google.common.base.Charsets; -import com.google.common.collect.Lists; -import com.google.common.io.Files; - -import freemarker.cache.TemplateLoader; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; -import freemarker.template.TemplateException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.ToolFactory; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.NullChange; -import org.eclipse.ltk.core.refactoring.TextFileChange; -import org.eclipse.swt.SWT; -import org.eclipse.text.edits.InsertEdit; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; -import org.osgi.framework.Constants; -import org.osgi.framework.Version; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -/** - * Handler which manages instantiating FreeMarker templates, copying resources - * and merging into existing files - */ -class TemplateHandler { - /** Highest supported format; templates with a higher number will be skipped - * <p> - * <ul> - * <li> 1: Initial format, supported by ADT 20 and up. - * <li> 2: ADT 21 and up. Boolean variables that have a default value and are not - * edited by the user would end up as strings in ADT 20; now they are always - * proper Booleans. Templates which rely on this should specify format >= 2. - * <li> 3: The wizard infrastructure passes the {@code isNewProject} boolean variable - * to indicate whether a wizard is created as part of a new blank project - * <li> 4: The templates now specify dependencies in the recipe file. - * </ul> - */ - static final int CURRENT_FORMAT = 4; - - /** - * Special marker indicating that this path refers to the special shared - * resource directory rather than being somewhere inside the root/ directory - * where all template specific resources are found - */ - private static final String VALUE_TEMPLATE_DIR = "$TEMPLATEDIR"; //$NON-NLS-1$ - - /** - * Directory within the template which contains the resources referenced - * from the template.xml file - */ - private static final String DATA_ROOT = "root"; //$NON-NLS-1$ - - /** - * Shared resource directory containing common resources shared among - * multiple templates - */ - private static final String RESOURCE_ROOT = "resources"; //$NON-NLS-1$ - - /** Reserved filename which describes each template */ - static final String TEMPLATE_XML = "template.xml"; //$NON-NLS-1$ - - // Various tags and attributes used in the template metadata files - template.xml, - // globals.xml.ftl, recipe.xml.ftl, etc. - - static final String TAG_MERGE = "merge"; //$NON-NLS-1$ - static final String TAG_EXECUTE = "execute"; //$NON-NLS-1$ - static final String TAG_GLOBALS = "globals"; //$NON-NLS-1$ - static final String TAG_GLOBAL = "global"; //$NON-NLS-1$ - static final String TAG_PARAMETER = "parameter"; //$NON-NLS-1$ - static final String TAG_COPY = "copy"; //$NON-NLS-1$ - static final String TAG_INSTANTIATE = "instantiate"; //$NON-NLS-1$ - static final String TAG_OPEN = "open"; //$NON-NLS-1$ - static final String TAG_THUMB = "thumb"; //$NON-NLS-1$ - static final String TAG_THUMBS = "thumbs"; //$NON-NLS-1$ - static final String TAG_DEPENDENCY = "dependency"; //$NON-NLS-1$ - static final String TAG_ICONS = "icons"; //$NON-NLS-1$ - static final String TAG_FORMFACTOR = "formfactor"; //$NON-NLS-1$ - static final String TAG_CATEGORY = "category"; //$NON-NLS-1$ - static final String ATTR_FORMAT = "format"; //$NON-NLS-1$ - static final String ATTR_REVISION = "revision"; //$NON-NLS-1$ - static final String ATTR_VALUE = "value"; //$NON-NLS-1$ - static final String ATTR_DEFAULT = "default"; //$NON-NLS-1$ - static final String ATTR_SUGGEST = "suggest"; //$NON-NLS-1$ - static final String ATTR_ID = "id"; //$NON-NLS-1$ - static final String ATTR_NAME = "name"; //$NON-NLS-1$ - static final String ATTR_DESCRIPTION = "description";//$NON-NLS-1$ - static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - static final String ATTR_HELP = "help"; //$NON-NLS-1$ - static final String ATTR_FILE = "file"; //$NON-NLS-1$ - static final String ATTR_TO = "to"; //$NON-NLS-1$ - static final String ATTR_FROM = "from"; //$NON-NLS-1$ - static final String ATTR_CONSTRAINTS = "constraints";//$NON-NLS-1$ - static final String ATTR_BACKGROUND = "background"; //$NON-NLS-1$ - static final String ATTR_FOREGROUND = "foreground"; //$NON-NLS-1$ - static final String ATTR_SHAPE = "shape"; //$NON-NLS-1$ - static final String ATTR_TRIM = "trim"; //$NON-NLS-1$ - static final String ATTR_PADDING = "padding"; //$NON-NLS-1$ - static final String ATTR_SOURCE_TYPE = "source"; //$NON-NLS-1$ - static final String ATTR_CLIPART_NAME = "clipartName";//$NON-NLS-1$ - static final String ATTR_TEXT = "text"; //$NON-NLS-1$ - static final String ATTR_SRC_DIR = "srcDir"; //$NON-NLS-1$ - static final String ATTR_SRC_OUT = "srcOut"; //$NON-NLS-1$ - static final String ATTR_RES_DIR = "resDir"; //$NON-NLS-1$ - static final String ATTR_RES_OUT = "resOut"; //$NON-NLS-1$ - static final String ATTR_MANIFEST_DIR = "manifestDir";//$NON-NLS-1$ - static final String ATTR_MANIFEST_OUT = "manifestOut";//$NON-NLS-1$ - static final String ATTR_PROJECT_DIR = "projectDir"; //$NON-NLS-1$ - static final String ATTR_PROJECT_OUT = "projectOut"; //$NON-NLS-1$ - static final String ATTR_MAVEN_URL = "mavenUrl"; //$NON-NLS-1$ - static final String ATTR_DEBUG_KEYSTORE_SHA1 = - "debugKeystoreSha1"; //$NON-NLS-1$ - - static final String CATEGORY_ACTIVITIES = "activities";//$NON-NLS-1$ - static final String CATEGORY_PROJECTS = "projects"; //$NON-NLS-1$ - static final String CATEGORY_OTHER = "other"; //$NON-NLS-1$ - - static final String MAVEN_SUPPORT_V4 = "support-v4"; //$NON-NLS-1$ - static final String MAVEN_SUPPORT_V13 = "support-v13"; //$NON-NLS-1$ - static final String MAVEN_APPCOMPAT = "appcompat-v7"; //$NON-NLS-1$ - - /** Default padding to apply in wizards around the thumbnail preview images */ - static final int PREVIEW_PADDING = 10; - - /** Default width to scale thumbnail preview images in wizards to */ - static final int PREVIEW_WIDTH = 200; - - /** - * List of files to open after the wizard has been created (these are - * identified by {@link #TAG_OPEN} elements in the recipe file - */ - private final List<String> mOpen = Lists.newArrayList(); - - /** - * List of actions to perform after the wizard has finished. - */ - protected List<Runnable> mFinalizingActions = Lists.newArrayList(); - - /** Path to the directory containing the templates */ - @NonNull - private final File mRootPath; - - /** The changes being processed by the template handler */ - private List<Change> mMergeChanges; - private List<Change> mTextChanges; - private List<Change> mOtherChanges; - - /** The project to write the template into */ - private IProject mProject; - - /** The template loader which is responsible for finding (and sharing) template files */ - private final MyTemplateLoader mLoader; - - /** Agree to all file-overwrites from now on? */ - private boolean mYesToAll = false; - - /** Is writing the template cancelled? */ - private boolean mNoToAll = false; - - /** - * Should files that we merge contents into be backed up? If yes, will - * create emacs-style tilde-file backups (filename.xml~) - */ - private boolean mBackupMergedFiles = true; - - /** - * Template metadata - */ - private TemplateMetadata mTemplate; - - private final TemplateManager mManager; - - /** Creates a new {@link TemplateHandler} for the given root path */ - static TemplateHandler createFromPath(File rootPath) { - return new TemplateHandler(rootPath, new TemplateManager()); - } - - /** Creates a new {@link TemplateHandler} for the template name, which should - * be relative to the templates directory */ - static TemplateHandler createFromName(String category, String name) { - TemplateManager manager = new TemplateManager(); - - // Use the TemplateManager iteration which should merge contents between the - // extras/templates/ and tools/templates folders and pick the most recent version - List<File> templates = manager.getTemplates(category); - for (File file : templates) { - if (file.getName().equals(name) && category.equals(file.getParentFile().getName())) { - return new TemplateHandler(file, manager); - } - } - - return new TemplateHandler(new File(getTemplateRootFolder(), - category + File.separator + name), manager); - } - - private TemplateHandler(File rootPath, TemplateManager manager) { - mRootPath = rootPath; - mManager = manager; - mLoader = new MyTemplateLoader(); - mLoader.setPrefix(mRootPath.getPath()); - } - - public TemplateManager getManager() { - return mManager; - } - - public void setBackupMergedFiles(boolean backupMergedFiles) { - mBackupMergedFiles = backupMergedFiles; - } - - @NonNull - public List<Change> render(IProject project, Map<String, Object> args) { - mOpen.clear(); - - mProject = project; - mMergeChanges = new ArrayList<Change>(); - mTextChanges = new ArrayList<Change>(); - mOtherChanges = new ArrayList<Change>(); - - // Render the instruction list template. - Map<String, Object> paramMap = createParameterMap(args); - Configuration freemarker = new Configuration(); - freemarker.setObjectWrapper(new DefaultObjectWrapper()); - freemarker.setTemplateLoader(mLoader); - - processVariables(freemarker, TEMPLATE_XML, paramMap); - - // Add the changes in the order where merges are shown first, then text files, - // and finally other files (like jars and icons which don't have previews). - List<Change> changes = new ArrayList<Change>(); - changes.addAll(mMergeChanges); - changes.addAll(mTextChanges); - changes.addAll(mOtherChanges); - return changes; - } - - Map<String, Object> createParameterMap(Map<String, Object> args) { - final Map<String, Object> paramMap = createBuiltinMap(); - - // Wizard parameters supplied by user, specific to this template - paramMap.putAll(args); - - return paramMap; - } - - /** Data model for the templates */ - static Map<String, Object> createBuiltinMap() { - // Create the data model. - final Map<String, Object> paramMap = new HashMap<String, Object>(); - - // Builtin conversion methods - paramMap.put("slashedPackageName", new FmSlashedPackageNameMethod()); //$NON-NLS-1$ - paramMap.put("camelCaseToUnderscore", new FmCamelCaseToUnderscoreMethod()); //$NON-NLS-1$ - paramMap.put("underscoreToCamelCase", new FmUnderscoreToCamelCaseMethod()); //$NON-NLS-1$ - paramMap.put("activityToLayout", new FmActivityToLayoutMethod()); //$NON-NLS-1$ - paramMap.put("layoutToActivity", new FmLayoutToActivityMethod()); //$NON-NLS-1$ - paramMap.put("classToResource", new FmClassNameToResourceMethod()); //$NON-NLS-1$ - paramMap.put("escapeXmlAttribute", new FmEscapeXmlStringMethod()); //$NON-NLS-1$ - paramMap.put("escapeXmlText", new FmEscapeXmlStringMethod()); //$NON-NLS-1$ - paramMap.put("escapeXmlString", new FmEscapeXmlStringMethod()); //$NON-NLS-1$ - paramMap.put("extractLetters", new FmExtractLettersMethod()); //$NON-NLS-1$ - - // This should be handled better: perhaps declared "required packages" as part of the - // inputs? (It would be better if we could conditionally disable template based - // on availability) - Map<String, String> builtin = new HashMap<String, String>(); - builtin.put("templatesRes", VALUE_TEMPLATE_DIR); //$NON-NLS-1$ - paramMap.put("android", builtin); //$NON-NLS-1$ - - return paramMap; - } - - static void addDirectoryParameters(Map<String, Object> parameters, IProject project) { - IPath srcDir = project.getFile(SdkConstants.SRC_FOLDER).getProjectRelativePath(); - parameters.put(ATTR_SRC_DIR, srcDir.toString()); - - IPath resDir = project.getFile(SdkConstants.RES_FOLDER).getProjectRelativePath(); - parameters.put(ATTR_RES_DIR, resDir.toString()); - - IPath manifestDir = project.getProjectRelativePath(); - parameters.put(ATTR_MANIFEST_DIR, manifestDir.toString()); - parameters.put(ATTR_MANIFEST_OUT, manifestDir.toString()); - - parameters.put(ATTR_PROJECT_DIR, manifestDir.toString()); - parameters.put(ATTR_PROJECT_OUT, manifestDir.toString()); - - parameters.put(ATTR_DEBUG_KEYSTORE_SHA1, ""); - } - - @Nullable - public TemplateMetadata getTemplate() { - if (mTemplate == null) { - mTemplate = mManager.getTemplate(mRootPath); - } - - return mTemplate; - } - - @NonNull - public String getResourcePath(String templateName) { - return new File(mRootPath.getPath(), templateName).getPath(); - } - - /** - * Load a text resource for the given relative path within the template - * - * @param relativePath relative path within the template - * @return the string contents of the template text file - */ - @Nullable - public String readTemplateTextResource(@NonNull String relativePath) { - try { - return Files.toString(new File(mRootPath, - relativePath.replace('/', File.separatorChar)), Charsets.UTF_8); - } catch (IOException e) { - AdtPlugin.log(e, null); - return null; - } - } - - @Nullable - public String readTemplateTextResource(@NonNull File file) { - assert file.isAbsolute(); - try { - return Files.toString(file, Charsets.UTF_8); - } catch (IOException e) { - AdtPlugin.log(e, null); - return null; - } - } - - /** - * Reads the contents of a resource - * - * @param relativePath the path relative to the template directory - * @return the binary data read from the file - */ - @Nullable - public byte[] readTemplateResource(@NonNull String relativePath) { - try { - return Files.toByteArray(new File(mRootPath, relativePath)); - } catch (IOException e) { - AdtPlugin.log(e, null); - return null; - } - } - - /** - * Most recent thrown exception during template instantiation. This should - * basically always be null. Used by unit tests to see if any template - * instantiation recorded a failure. - */ - @VisibleForTesting - public static Exception sMostRecentException; - - /** Read the given FreeMarker file and process the variable definitions */ - private void processVariables(final Configuration freemarker, - String file, final Map<String, Object> paramMap) { - try { - String xml; - if (file.endsWith(DOT_XML)) { - // Just read the file - xml = readTemplateTextResource(file); - if (xml == null) { - return; - } - } else { - mLoader.setTemplateFile(new File(mRootPath, file)); - Template inputsTemplate = freemarker.getTemplate(file); - StringWriter out = new StringWriter(); - inputsTemplate.process(paramMap, out); - out.flush(); - xml = out.toString(); - } - - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(new ByteArrayInputStream(xml.getBytes()), new DefaultHandler() { - @Override - public void startElement(String uri, String localName, String name, - Attributes attributes) - throws SAXException { - if (TAG_PARAMETER.equals(name)) { - String id = attributes.getValue(ATTR_ID); - if (!paramMap.containsKey(id)) { - String value = attributes.getValue(ATTR_DEFAULT); - Object mapValue = value; - if (value != null && !value.isEmpty()) { - String type = attributes.getValue(ATTR_TYPE); - if ("boolean".equals(type)) { //$NON-NLS-1$ - mapValue = Boolean.valueOf(value); - } - } - paramMap.put(id, mapValue); - } - } else if (TAG_GLOBAL.equals(name)) { - String id = attributes.getValue(ATTR_ID); - if (!paramMap.containsKey(id)) { - paramMap.put(id, TypedVariable.parseGlobal(attributes)); - } - } else if (TAG_GLOBALS.equals(name)) { - // Handle evaluation of variables - String path = attributes.getValue(ATTR_FILE); - if (path != null) { - processVariables(freemarker, path, paramMap); - } // else: <globals> root element - } else if (TAG_EXECUTE.equals(name)) { - String path = attributes.getValue(ATTR_FILE); - if (path != null) { - execute(freemarker, path, paramMap); - } - } else if (TAG_DEPENDENCY.equals(name)) { - String dependencyName = attributes.getValue(ATTR_NAME); - if (dependencyName.equals(SUPPORT_LIBRARY_NAME)) { - // We assume the revision requirement has been satisfied - // by the wizard - File path = AddSupportJarAction.getSupportJarFile(); - if (path != null) { - IPath to = getTargetPath(FD_NATIVE_LIBS +'/' + path.getName()); - try { - copy(path, to); - } catch (IOException ioe) { - AdtPlugin.log(ioe, null); - } - } - } - } else if (!name.equals("template") && !name.equals(TAG_CATEGORY) && - !name.equals(TAG_FORMFACTOR) && !name.equals("option") && - !name.equals(TAG_THUMBS) && !name.equals(TAG_THUMB) && - !name.equals(TAG_ICONS)) { - System.err.println("WARNING: Unknown template directive " + name); - } - } - }); - } catch (Exception e) { - sMostRecentException = e; - AdtPlugin.log(e, null); - } - } - - @SuppressWarnings("unused") - private boolean canOverwrite(File file) { - if (file.exists()) { - // Warn that the file already exists and ask the user what to do - if (!mYesToAll) { - MessageDialog dialog = new MessageDialog(null, "File Already Exists", null, - String.format( - "%1$s already exists.\nWould you like to replace it?", - file.getPath()), - MessageDialog.QUESTION, new String[] { - // Yes will be moved to the end because it's the default - "Yes", "No", "Cancel", "Yes to All" - }, 0); - int result = dialog.open(); - switch (result) { - case 0: - // Yes - break; - case 3: - // Yes to all - mYesToAll = true; - break; - case 1: - // No - return false; - case SWT.DEFAULT: - case 2: - // Cancel - mNoToAll = true; - return false; - } - } - - if (mBackupMergedFiles) { - return makeBackup(file); - } else { - return file.delete(); - } - } - - return true; - } - - /** Executes the given recipe file: copying, merging, instantiating, opening files etc */ - private void execute( - final Configuration freemarker, - String file, - final Map<String, Object> paramMap) { - try { - mLoader.setTemplateFile(new File(mRootPath, file)); - Template freemarkerTemplate = freemarker.getTemplate(file); - - StringWriter out = new StringWriter(); - freemarkerTemplate.process(paramMap, out); - out.flush(); - String xml = out.toString(); - - // Parse and execute the resulting instruction list. - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - - saxParser.parse(new ByteArrayInputStream(xml.getBytes()), - new DefaultHandler() { - @Override - public void startElement(String uri, String localName, String name, - Attributes attributes) - throws SAXException { - if (mNoToAll) { - return; - } - - try { - boolean instantiate = TAG_INSTANTIATE.equals(name); - if (TAG_COPY.equals(name) || instantiate) { - String fromPath = attributes.getValue(ATTR_FROM); - String toPath = attributes.getValue(ATTR_TO); - if (toPath == null || toPath.isEmpty()) { - toPath = attributes.getValue(ATTR_FROM); - toPath = AdtUtils.stripSuffix(toPath, DOT_FTL); - } - IPath to = getTargetPath(toPath); - if (instantiate) { - instantiate(freemarker, paramMap, fromPath, to); - } else { - copyTemplateResource(fromPath, to); - } - } else if (TAG_MERGE.equals(name)) { - String fromPath = attributes.getValue(ATTR_FROM); - String toPath = attributes.getValue(ATTR_TO); - if (toPath == null || toPath.isEmpty()) { - toPath = attributes.getValue(ATTR_FROM); - toPath = AdtUtils.stripSuffix(toPath, DOT_FTL); - } - // Resources in template.xml are located within root/ - IPath to = getTargetPath(toPath); - merge(freemarker, paramMap, fromPath, to); - } else if (name.equals(TAG_OPEN)) { - // The relative path here is within the output directory: - String relativePath = attributes.getValue(ATTR_FILE); - if (relativePath != null && !relativePath.isEmpty()) { - mOpen.add(relativePath); - } - } else if (TAG_DEPENDENCY.equals(name)) { - String dependencyUrl = attributes.getValue(ATTR_MAVEN_URL); - File path; - if (dependencyUrl.contains(MAVEN_SUPPORT_V4)) { - // We assume the revision requirement has been satisfied - // by the wizard - path = AddSupportJarAction.getSupportJarFile(); - } else if (dependencyUrl.contains(MAVEN_SUPPORT_V13)) { - path = AddSupportJarAction.getSupport13JarFile(); - } else if (dependencyUrl.contains(MAVEN_APPCOMPAT)) { - path = null; - mFinalizingActions.add(new Runnable() { - @Override - public void run() { - AddSupportJarAction.installAppCompatLibrary(mProject, true); - } - }); - } else { - path = null; - System.err.println("WARNING: Unknown dependency type"); - } - - if (path != null) { - IPath to = getTargetPath(FD_NATIVE_LIBS +'/' + path.getName()); - try { - copy(path, to); - } catch (IOException ioe) { - AdtPlugin.log(ioe, null); - } - } - } else if (!name.equals("recipe") && !name.equals(TAG_DEPENDENCY)) { //$NON-NLS-1$ - System.err.println("WARNING: Unknown template directive " + name); - } - } catch (Exception e) { - sMostRecentException = e; - AdtPlugin.log(e, null); - } - } - }); - - } catch (Exception e) { - sMostRecentException = e; - AdtPlugin.log(e, null); - } - } - - @NonNull - private File getFullPath(@NonNull String fromPath) { - if (fromPath.startsWith(VALUE_TEMPLATE_DIR)) { - return new File(getTemplateRootFolder(), RESOURCE_ROOT + File.separator - + fromPath.substring(VALUE_TEMPLATE_DIR.length() + 1).replace('/', - File.separatorChar)); - } - return new File(mRootPath, DATA_ROOT + File.separator + fromPath); - } - - @NonNull - private IPath getTargetPath(@NonNull String relative) { - if (relative.indexOf('\\') != -1) { - relative = relative.replace('\\', '/'); - } - return new Path(relative); - } - - @NonNull - private IFile getTargetFile(@NonNull IPath path) { - return mProject.getFile(path); - } - - private void merge( - @NonNull final Configuration freemarker, - @NonNull final Map<String, Object> paramMap, - @NonNull String relativeFrom, - @NonNull IPath toPath) throws IOException, TemplateException { - - String currentXml = null; - - IFile to = getTargetFile(toPath); - if (to.exists()) { - currentXml = AdtPlugin.readFile(to); - } - - if (currentXml == null) { - // The target file doesn't exist: don't merge, just copy - boolean instantiate = relativeFrom.endsWith(DOT_FTL); - if (instantiate) { - instantiate(freemarker, paramMap, relativeFrom, toPath); - } else { - copyTemplateResource(relativeFrom, toPath); - } - return; - } - - if (!to.getFileExtension().equals(EXT_XML)) { - throw new RuntimeException("Only XML files can be merged at this point: " + to); - } - - String xml = null; - File from = getFullPath(relativeFrom); - if (relativeFrom.endsWith(DOT_FTL)) { - // Perform template substitution of the template prior to merging - mLoader.setTemplateFile(from); - Template template = freemarker.getTemplate(from.getName()); - Writer out = new StringWriter(); - template.process(paramMap, out); - out.flush(); - xml = out.toString(); - } else { - xml = readTemplateTextResource(from); - if (xml == null) { - return; - } - } - - Document currentDocument = DomUtilities.parseStructuredDocument(currentXml); - assert currentDocument != null : currentXml; - Document fragment = DomUtilities.parseStructuredDocument(xml); - assert fragment != null : xml; - - XmlFormatStyle formatStyle = XmlFormatStyle.MANIFEST; - boolean modified; - boolean ok; - String fileName = to.getName(); - if (fileName.equals(SdkConstants.FN_ANDROID_MANIFEST_XML)) { - modified = ok = mergeManifest(currentDocument, fragment); - } else { - // Merge plain XML files - String parentFolderName = to.getParent().getName(); - ResourceFolderType folderType = ResourceFolderType.getFolderType(parentFolderName); - if (folderType != null) { - formatStyle = EclipseXmlPrettyPrinter.getForFile(toPath); - } else { - formatStyle = XmlFormatStyle.FILE; - } - - modified = mergeResourceFile(currentDocument, fragment, folderType, paramMap); - ok = true; - } - - // Finally write out the merged file (formatting etc) - String contents = null; - if (ok) { - if (modified) { - contents = EclipseXmlPrettyPrinter.prettyPrint(currentDocument, - EclipseXmlFormatPreferences.create(), formatStyle, null, - currentXml.endsWith("\n")); //$NON-NLS-1$ - } - } else { - // Just insert into file along with comment, using the "standard" conflict - // syntax that many tools and editors recognize. - String sep = SdkUtils.getLineSeparator(); - contents = - "<<<<<<< Original" + sep - + currentXml + sep - + "=======" + sep - + xml - + ">>>>>>> Added" + sep; - } - - if (contents != null) { - TextFileChange change = new TextFileChange("Merge " + fileName, to); - MultiTextEdit rootEdit = new MultiTextEdit(); - rootEdit.addChild(new ReplaceEdit(0, currentXml.length(), contents)); - change.setEdit(rootEdit); - change.setTextType(SdkConstants.EXT_XML); - mMergeChanges.add(change); - } - } - - /** Merges the given resource file contents into the given resource file - * @param paramMap */ - private static boolean mergeResourceFile(Document currentDocument, Document fragment, - ResourceFolderType folderType, Map<String, Object> paramMap) { - boolean modified = false; - - // Copy namespace declarations - NamedNodeMap attributes = fragment.getDocumentElement().getAttributes(); - if (attributes != null) { - for (int i = 0, n = attributes.getLength(); i < n; i++) { - Attr attribute = (Attr) attributes.item(i); - if (attribute.getName().startsWith(XMLNS_PREFIX)) { - currentDocument.getDocumentElement().setAttribute(attribute.getName(), - attribute.getValue()); - } - } - } - - // For layouts for example, I want to *append* inside the root all the - // contents of the new file. - // But for resources for example, I want to combine elements which specify - // the same name or id attribute. - // For elements like manifest files we need to insert stuff at the right - // location in a nested way (activities in the application element etc) - // but that doesn't happen for the other file types. - Element root = fragment.getDocumentElement(); - NodeList children = root.getChildNodes(); - List<Node> nodes = new ArrayList<Node>(children.getLength()); - for (int i = children.getLength() - 1; i >= 0; i--) { - Node child = children.item(i); - nodes.add(child); - root.removeChild(child); - } - Collections.reverse(nodes); - - root = currentDocument.getDocumentElement(); - - if (folderType == ResourceFolderType.VALUES) { - // Try to merge items of the same name - Map<String, Node> old = new HashMap<String, Node>(); - NodeList newSiblings = root.getChildNodes(); - for (int i = newSiblings.getLength() - 1; i >= 0; i--) { - Node child = newSiblings.item(i); - if (child.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) child; - String name = getResourceId(element); - if (name != null) { - old.put(name, element); - } - } - } - - for (Node node : nodes) { - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - String name = getResourceId(element); - Node replace = name != null ? old.get(name) : null; - if (replace != null) { - // There is an existing item with the same id: just replace it - // ACTUALLY -- let's NOT change it. - // Let's say you've used the activity wizard once, and it - // emits some configuration parameter as a resource that - // it depends on, say "padding". Then the user goes and - // tweaks the padding to some other number. - // Now running the wizard a *second* time for some new activity, - // we should NOT go and set the value back to the template's - // default! - //root.replaceChild(node, replace); - - // ... ON THE OTHER HAND... What if it's a parameter class - // (where the template rewrites a common attribute). Here it's - // really confusing if the new parameter is not set. This is - // really an error in the template, since we shouldn't have conflicts - // like that, but we need to do something to help track this down. - AdtPlugin.log(null, - "Warning: Ignoring name conflict in resource file for name %1$s", - name); - } else { - root.appendChild(node); - modified = true; - } - } - } - } else { - // In other file types, such as layouts, just append all the new content - // at the end. - for (Node node : nodes) { - root.appendChild(node); - modified = true; - } - } - return modified; - } - - /** Merges the given manifest fragment into the given manifest file */ - private static boolean mergeManifest(Document currentManifest, Document fragment) { - // TODO change MergerLog.wrapSdkLog by a custom IMergerLog that will create - // and maintain error markers. - - // Transfer package element from manifest to merged in root; required by - // manifest merger - Element fragmentRoot = fragment.getDocumentElement(); - Element manifestRoot = currentManifest.getDocumentElement(); - if (fragmentRoot == null || manifestRoot == null) { - return false; - } - String pkg = fragmentRoot.getAttribute(ATTR_PACKAGE); - if (pkg == null || pkg.isEmpty()) { - pkg = manifestRoot.getAttribute(ATTR_PACKAGE); - if (pkg != null && !pkg.isEmpty()) { - fragmentRoot.setAttribute(ATTR_PACKAGE, pkg); - } - } - - ManifestMerger merger = new ManifestMerger( - MergerLog.wrapSdkLog(AdtPlugin.getDefault()), - new AdtManifestMergeCallback()).setExtractPackagePrefix(true); - return currentManifest != null && - fragment != null && - merger.process(currentManifest, fragment); - } - - /** - * Makes a backup of the given file, if it exists, by renaming it to name~ - * (and removing an old name~ file if it exists) - */ - private static boolean makeBackup(File file) { - if (!file.exists()) { - return true; - } - if (file.isDirectory()) { - return false; - } - - File backupFile = new File(file.getParentFile(), file.getName() + '~'); - if (backupFile.exists()) { - backupFile.delete(); - } - return file.renameTo(backupFile); - } - - private static String getResourceId(Element element) { - String name = element.getAttribute(ATTR_NAME); - if (name == null) { - name = element.getAttribute(ATTR_ID); - } - - return name; - } - - /** Instantiates the given template file into the given output file */ - private void instantiate( - @NonNull final Configuration freemarker, - @NonNull final Map<String, Object> paramMap, - @NonNull String relativeFrom, - @NonNull IPath to) throws IOException, TemplateException { - // For now, treat extension-less files as directories... this isn't quite right - // so I should refine this! Maybe with a unique attribute in the template file? - boolean isDirectory = relativeFrom.indexOf('.') == -1; - if (isDirectory) { - // It's a directory - copyTemplateResource(relativeFrom, to); - } else { - File from = getFullPath(relativeFrom); - mLoader.setTemplateFile(from); - Template template = freemarker.getTemplate(from.getName()); - Writer out = new StringWriter(1024); - template.process(paramMap, out); - out.flush(); - String contents = out.toString(); - - contents = format(mProject, contents, to); - IFile targetFile = getTargetFile(to); - TextFileChange change = createNewFileChange(targetFile); - MultiTextEdit rootEdit = new MultiTextEdit(); - rootEdit.addChild(new InsertEdit(0, contents)); - change.setEdit(rootEdit); - mTextChanges.add(change); - } - } - - private static String format(IProject project, String contents, IPath to) { - String name = to.lastSegment(); - if (name.endsWith(DOT_XML)) { - XmlFormatStyle formatStyle = EclipseXmlPrettyPrinter.getForFile(to); - EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create(); - return EclipseXmlPrettyPrinter.prettyPrint(contents, prefs, formatStyle, null); - } else if (name.endsWith(DOT_JAVA)) { - Map<?, ?> options = null; - if (project != null && project.isAccessible()) { - try { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - if (javaProject != null) { - options = javaProject.getOptions(true); - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - } - if (options == null) { - options = JavaCore.getOptions(); - } - - CodeFormatter formatter = ToolFactory.createCodeFormatter(options); - - try { - IDocument doc = new org.eclipse.jface.text.Document(); - // format the file (the meat and potatoes) - doc.set(contents); - TextEdit edit = formatter.format( - CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, - contents, 0, contents.length(), 0, null); - if (edit != null) { - edit.apply(doc); - } - - return doc.get(); - } catch (Exception e) { - AdtPlugin.log(e, null); - } - } - - return contents; - } - - private static TextFileChange createNewFileChange(IFile targetFile) { - String fileName = targetFile.getName(); - String message; - if (targetFile.exists()) { - message = String.format("Replace %1$s", fileName); - } else { - message = String.format("Create %1$s", fileName); - } - - TextFileChange change = new TextFileChange(message, targetFile) { - @Override - protected IDocument acquireDocument(IProgressMonitor pm) throws CoreException { - IDocument document = super.acquireDocument(pm); - - // In our case, we know we *always* use this TextFileChange - // to *create* files, we're not appending to existing files. - // However, due to the following bug we can end up with cached - // contents of previously deleted files that happened to have the - // same file name: - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=390402 - // Therefore, as a workaround, wipe out the cached contents here - if (document.getLength() > 0) { - try { - document.replace(0, document.getLength(), ""); - } catch (BadLocationException e) { - // pass - } - } - - return document; - } - }; - change.setTextType(fileName.substring(fileName.lastIndexOf('.') + 1)); - return change; - } - - /** - * Returns the list of files to open when the template has been created - * - * @return the list of files to open - */ - @NonNull - public List<String> getFilesToOpen() { - return mOpen; - } - - /** - * Returns the list of actions to perform when the template has been created - * - * @return the list of actions to perform - */ - @NonNull - public List<Runnable> getFinalizingActions() { - return mFinalizingActions; - } - - /** Copy a template resource */ - private final void copyTemplateResource( - @NonNull String relativeFrom, - @NonNull IPath output) throws IOException { - File from = getFullPath(relativeFrom); - copy(from, output); - } - - /** Returns true if the given file contains the given bytes */ - private static boolean isIdentical(@Nullable byte[] data, @NonNull IFile dest) { - assert dest.exists(); - byte[] existing = AdtUtils.readData(dest); - return Arrays.equals(existing, data); - } - - /** - * Copies the given source file into the given destination file (where the - * source is allowed to be a directory, in which case the whole directory is - * copied recursively) - */ - private void copy(File src, IPath path) throws IOException { - if (src.isDirectory()) { - File[] children = src.listFiles(); - if (children != null) { - for (File child : children) { - copy(child, path.append(child.getName())); - } - } - } else { - IResource dest = mProject.getFile(path); - if (dest.exists() && !(dest instanceof IFile)) {// Don't attempt to overwrite a folder - assert false : dest.getClass().getName(); - return; - } - IFile file = (IFile) dest; - String targetName = path.lastSegment(); - if (dest instanceof IFile) { - if (dest.exists() && isIdentical(Files.toByteArray(src), file)) { - String label = String.format( - "Not overwriting %1$s because the files are identical", targetName); - NullChange change = new NullChange(label); - change.setEnabled(false); - mOtherChanges.add(change); - return; - } - } - - if (targetName.endsWith(DOT_XML) - || targetName.endsWith(DOT_JAVA) - || targetName.endsWith(DOT_TXT) - || targetName.endsWith(DOT_RS) - || targetName.endsWith(DOT_AIDL) - || targetName.endsWith(DOT_SVG)) { - - String newFile = Files.toString(src, Charsets.UTF_8); - newFile = format(mProject, newFile, path); - - TextFileChange addFile = createNewFileChange(file); - addFile.setEdit(new InsertEdit(0, newFile)); - mTextChanges.add(addFile); - } else { - // Write binary file: Need custom change for that - IPath workspacePath = mProject.getFullPath().append(path); - mOtherChanges.add(new CreateFileChange(targetName, workspacePath, src)); - } - } - } - - /** - * A custom {@link TemplateLoader} which locates and provides templates - * within the plugin .jar file - */ - private static final class MyTemplateLoader implements TemplateLoader { - private String mPrefix; - - public void setPrefix(String prefix) { - mPrefix = prefix; - } - - public void setTemplateFile(File file) { - setTemplateParent(file.getParentFile()); - } - - public void setTemplateParent(File parent) { - mPrefix = parent.getPath(); - } - - @Override - public Reader getReader(Object templateSource, String encoding) throws IOException { - URL url = (URL) templateSource; - return new InputStreamReader(url.openStream(), encoding); - } - - @Override - public long getLastModified(Object templateSource) { - return 0; - } - - @Override - public Object findTemplateSource(String name) throws IOException { - String path = mPrefix != null ? mPrefix + '/' + name : name; - File file = new File(path); - if (file.exists()) { - return file.toURI().toURL(); - } - return null; - } - - @Override - public void closeTemplateSource(Object templateSource) throws IOException { - } - } - - /** - * Validates this template to make sure it's supported - * @param currentMinSdk the minimum SDK in the project, or -1 or 0 if unknown (e.g. codename) - * @param buildApi the build API, or -1 or 0 if unknown (e.g. codename) - * - * @return a status object with the error, or null if there is no problem - */ - @SuppressWarnings("cast") // In Eclipse 3.6.2 cast below is needed - @Nullable - public IStatus validateTemplate(int currentMinSdk, int buildApi) { - TemplateMetadata template = getTemplate(); - if (template == null) { - return null; - } - if (!template.isSupported()) { - String versionString = (String) AdtPlugin.getDefault().getBundle().getHeaders().get( - Constants.BUNDLE_VERSION); - Version version = new Version(versionString); - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("This template requires a more recent version of the " + - "Android Eclipse plugin. Please update from version %1$d.%2$d.%3$d.", - version.getMajor(), version.getMinor(), version.getMicro())); - } - int templateMinSdk = template.getMinSdk(); - if (templateMinSdk > currentMinSdk && currentMinSdk >= 1) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("This template requires a minimum SDK version of at " + - "least %1$d, and the current min version is %2$d", - templateMinSdk, currentMinSdk)); - } - int templateMinBuildApi = template.getMinBuildApi(); - if (templateMinBuildApi > buildApi && buildApi >= 1) { - return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - String.format("This template requires a build target API version of at " + - "least %1$d, and the current version is %2$d", - templateMinBuildApi, buildApi)); - } - - return null; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateManager.java deleted file mode 100644 index 30dd09e31..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateManager.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.SdkConstants.FD_EXTRAS; -import static com.android.SdkConstants.FD_TEMPLATES; -import static com.android.SdkConstants.FD_TOOLS; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TEMPLATE_XML; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; -import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; -import com.google.common.base.Charsets; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.io.Files; - -import org.w3c.dom.Document; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** Handles locating templates and providing template metadata */ -public class TemplateManager { - private static final Set<String> EXCLUDED_CATEGORIES = Sets.newHashSet("Folder", "Google"); - private static final Set<String> EXCLUDED_FORMFACTORS = Sets.newHashSet("Wear", "TV"); - - TemplateManager() { - } - - /** @return the root folder containing templates */ - @Nullable - public static File getTemplateRootFolder() { - String location = AdtPrefs.getPrefs().getOsSdkFolder(); - if (location != null) { - File folder = new File(location, FD_TOOLS + File.separator + FD_TEMPLATES); - if (folder.isDirectory()) { - return folder; - } - } - - return null; - } - - /** @return the root folder containing extra templates */ - @NonNull - public static List<File> getExtraTemplateRootFolders() { - List<File> folders = new ArrayList<File>(); - String location = AdtPrefs.getPrefs().getOsSdkFolder(); - if (location != null) { - File extras = new File(location, FD_EXTRAS); - if (extras.isDirectory()) { - for (File vendor : AdtUtils.listFiles(extras)) { - if (!vendor.isDirectory()) { - continue; - } - for (File pkg : AdtUtils.listFiles(vendor)) { - if (pkg.isDirectory()) { - File folder = new File(pkg, FD_TEMPLATES); - if (folder.isDirectory()) { - folders.add(folder); - } - } - } - } - - // Legacy - File folder = new File(extras, FD_TEMPLATES); - if (folder.isDirectory()) { - folders.add(folder); - } - } - } - - return folders; - } - - /** - * Returns a template file under the given root, if it exists - * - * @param root the root folder - * @param relativePath the relative path - * @return a template file under the given root, if it exists - */ - @Nullable - public static File getTemplateLocation(@NonNull File root, @NonNull String relativePath) { - File templateRoot = getTemplateRootFolder(); - if (templateRoot != null) { - String rootPath = root.getPath(); - File templateFile = new File(templateRoot, - rootPath.replace('/', File.separatorChar) + File.separator - + relativePath.replace('/', File.separatorChar)); - if (templateFile.exists()) { - return templateFile; - } - } - - return null; - } - - /** - * Returns a template file under one of the available roots, if it exists - * - * @param relativePath the relative path - * @return a template file under one of the available roots, if it exists - */ - @Nullable - public static File getTemplateLocation(@NonNull String relativePath) { - File templateRoot = getTemplateRootFolder(); - if (templateRoot != null) { - File templateFile = new File(templateRoot, - relativePath.replace('/', File.separatorChar)); - if (templateFile.exists()) { - return templateFile; - } - } - - return null; - - } - - /** - * Returns all the templates with the given prefix - * - * @param folder the folder prefix - * @return the available templates - */ - @NonNull - List<File> getTemplates(@NonNull String folder) { - List<File> templates = new ArrayList<File>(); - Map<String, File> templateNames = Maps.newHashMap(); - File root = getTemplateRootFolder(); - if (root != null) { - File[] files = new File(root, folder).listFiles(); - if (files != null) { - for (File file : files) { - if (file.isDirectory()) { // Avoid .DS_Store etc - templates.add(file); - templateNames.put(file.getName(), file); - } - } - } - } - - // Add in templates from extras/ as well. - for (File extra : getExtraTemplateRootFolders()) { - File[] files = new File(extra, folder).listFiles(); - if (files != null) { - for (File file : files) { - if (file.isDirectory()) { - File replaces = templateNames.get(file.getName()); - if (replaces != null) { - int compare = compareTemplates(replaces, file); - if (compare > 0) { - int index = templates.indexOf(replaces); - if (index != -1) { - templates.set(index, file); - } else { - templates.add(file); - } - } - } else { - templates.add(file); - } - } - } - } - } - - // Sort by file name (not path as is File's default) - if (templates.size() > 1) { - Collections.sort(templates, new Comparator<File>() { - @Override - public int compare(File file1, File file2) { - return file1.getName().compareTo(file2.getName()); - } - }); - } - - return templates; - } - - /** - * Compare two files, and return the one with the HIGHEST revision, and if - * the same, most recently modified - */ - private int compareTemplates(File file1, File file2) { - TemplateMetadata template1 = getTemplate(file1); - TemplateMetadata template2 = getTemplate(file2); - - if (template1 == null) { - return 1; - } else if (template2 == null) { - return -1; - } else { - int delta = template2.getRevision() - template1.getRevision(); - if (delta == 0) { - delta = (int) (file2.lastModified() - file1.lastModified()); - } - return delta; - } - } - - /** Cache for {@link #getTemplate()} */ - private Map<File, TemplateMetadata> mTemplateMap; - - @Nullable - TemplateMetadata getTemplate(File templateDir) { - if (mTemplateMap != null) { - TemplateMetadata metadata = mTemplateMap.get(templateDir); - if (metadata != null) { - return metadata; - } - } else { - mTemplateMap = Maps.newHashMap(); - } - - try { - File templateFile = new File(templateDir, TEMPLATE_XML); - if (templateFile.isFile()) { - String xml = Files.toString(templateFile, Charsets.UTF_8); - Document doc = DomUtilities.parseDocument(xml, true); - if (doc != null && doc.getDocumentElement() != null) { - TemplateMetadata metadata = new TemplateMetadata(doc); - if (EXCLUDED_CATEGORIES.contains(metadata.getCategory()) || - EXCLUDED_FORMFACTORS.contains(metadata.getFormFactor())) { - return null; - } - mTemplateMap.put(templateDir, metadata); - return metadata; - } - } - } catch (IOException e) { - AdtPlugin.log(e, null); - } - - return null; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java deleted file mode 100644 index 4ce7d74c2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_BUILD_API; -import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_REVISION; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_BACKGROUND; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_CLIPART_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_DESCRIPTION; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_FOREGROUND; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_FORMAT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_NAME; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_PADDING; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SHAPE; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SOURCE_TYPE; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TEXT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TRIM; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TYPE; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_VALUE; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.CURRENT_FORMAT; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_DEPENDENCY; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_ICONS; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_PARAMETER; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_THUMB; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_FORMFACTOR; -import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_CATEGORY; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.assetstudiolib.GraphicGenerator; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.assetstudio.AssetType; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState.SourceType; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils; -import com.android.utils.Pair; -import com.google.common.collect.Lists; - -import org.eclipse.core.resources.IProject; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.RGB; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** An ADT template along with metadata */ -class TemplateMetadata { - private final Document mDocument; - private final List<Parameter> mParameters; - private final Map<String, Parameter> mParameterMap; - private List<Pair<String, Integer>> mDependencies; - private Integer mMinApi; - private Integer mMinBuildApi; - private Integer mRevision; - private boolean mNoIcons; - private CreateAssetSetWizardState mIconState; - private String mFormFactor; - private String mCategory; - - TemplateMetadata(@NonNull Document document) { - mDocument = document; - - NodeList parameters = mDocument.getElementsByTagName(TAG_PARAMETER); - mParameters = new ArrayList<Parameter>(parameters.getLength()); - mParameterMap = new HashMap<String, Parameter>(parameters.getLength()); - for (int index = 0, max = parameters.getLength(); index < max; index++) { - Element element = (Element) parameters.item(index); - Parameter parameter = new Parameter(this, element); - mParameters.add(parameter); - if (parameter.id != null) { - mParameterMap.put(parameter.id, parameter); - } - } - } - - boolean isSupported() { - String versionString = mDocument.getDocumentElement().getAttribute(ATTR_FORMAT); - if (versionString != null && !versionString.isEmpty()) { - try { - int version = Integer.parseInt(versionString); - return version <= CURRENT_FORMAT; - } catch (NumberFormatException nufe) { - return false; - } - } - - // Older templates without version specified: supported - return true; - } - - @Nullable - String getTitle() { - String name = mDocument.getDocumentElement().getAttribute(ATTR_NAME); - if (name != null && !name.isEmpty()) { - return name; - } - - return null; - } - - @Nullable - String getDescription() { - String description = mDocument.getDocumentElement().getAttribute(ATTR_DESCRIPTION); - if (description != null && !description.isEmpty()) { - return description; - } - - return null; - } - - int getMinSdk() { - if (mMinApi == null) { - mMinApi = 1; - String api = mDocument.getDocumentElement().getAttribute(ATTR_MIN_API); - if (api != null && !api.isEmpty()) { - try { - mMinApi = Integer.parseInt(api); - } catch (NumberFormatException nufe) { - // Templates aren't allowed to contain codenames, should always be an integer - AdtPlugin.log(nufe, null); - mMinApi = 1; - } - } - } - - return mMinApi.intValue(); - } - - int getMinBuildApi() { - if (mMinBuildApi == null) { - mMinBuildApi = 1; - String api = mDocument.getDocumentElement().getAttribute(ATTR_MIN_BUILD_API); - if (api != null && !api.isEmpty()) { - try { - mMinBuildApi = Integer.parseInt(api); - } catch (NumberFormatException nufe) { - // Templates aren't allowed to contain codenames, should always be an integer - AdtPlugin.log(nufe, null); - mMinBuildApi = 1; - } - } - } - - return mMinBuildApi.intValue(); - } - - public int getRevision() { - if (mRevision == null) { - mRevision = 1; - String revision = mDocument.getDocumentElement().getAttribute(ATTR_REVISION); - if (revision != null && !revision.isEmpty()) { - try { - mRevision = Integer.parseInt(revision); - } catch (NumberFormatException nufe) { - AdtPlugin.log(nufe, null); - mRevision = 1; - } - } - } - - return mRevision.intValue(); - } - - public String getFormFactor() { - if (mFormFactor == null) { - mFormFactor = "Mobile"; - - NodeList formfactorDeclarations = mDocument.getElementsByTagName(TAG_FORMFACTOR); - if (formfactorDeclarations.getLength() > 0) { - Element element = (Element) formfactorDeclarations.item(0); - String formFactor = element.getAttribute(ATTR_VALUE); - if (formFactor != null && !formFactor.isEmpty()) { - mFormFactor = formFactor; - } - } - } - return mFormFactor; - } - - public String getCategory() { - if (mCategory == null) { - mCategory = ""; - NodeList categories = mDocument.getElementsByTagName(TAG_CATEGORY); - if (categories.getLength() > 0) { - Element element = (Element) categories.item(0); - String category = element.getAttribute(ATTR_VALUE); - if (category != null && !category.isEmpty()) { - mCategory = category; - } - } - } - return mCategory; - } - - /** - * Returns a suitable icon wizard state instance if this wizard requests - * icons to be created, and null otherwise - * - * @return icon wizard state or null - */ - @Nullable - public CreateAssetSetWizardState getIconState(IProject project) { - if (mIconState == null && !mNoIcons) { - NodeList icons = mDocument.getElementsByTagName(TAG_ICONS); - if (icons.getLength() < 1) { - mNoIcons = true; - return null; - } - Element icon = (Element) icons.item(0); - - mIconState = new CreateAssetSetWizardState(); - mIconState.project = project; - - String typeString = getAttributeOrNull(icon, ATTR_TYPE); - if (typeString != null) { - typeString = typeString.toUpperCase(Locale.US); - boolean found = false; - for (AssetType type : AssetType.values()) { - if (typeString.equals(type.name())) { - mIconState.type = type; - found = true; - break; - } - } - if (!found) { - AdtPlugin.log(null, "Unknown asset type %1$s", typeString); - } - } - - mIconState.outputName = getAttributeOrNull(icon, ATTR_NAME); - if (mIconState.outputName != null) { - // Register parameter such that if it is referencing other values, it gets - // updated when other values are edited - Parameter outputParameter = new Parameter(this, - Parameter.Type.STRING, "_iconname", mIconState.outputName); //$NON-NLS-1$ - getParameters().add(outputParameter); - } - - RGB background = getRgb(icon, ATTR_BACKGROUND); - if (background != null) { - mIconState.background = background; - } - RGB foreground = getRgb(icon, ATTR_FOREGROUND); - if (foreground != null) { - mIconState.foreground = foreground; - } - String shapeString = getAttributeOrNull(icon, ATTR_SHAPE); - if (shapeString != null) { - shapeString = shapeString.toUpperCase(Locale.US); - boolean found = false; - for (GraphicGenerator.Shape shape : GraphicGenerator.Shape.values()) { - if (shapeString.equals(shape.name())) { - mIconState.shape = shape; - found = true; - break; - } - } - if (!found) { - AdtPlugin.log(null, "Unknown shape %1$s", shapeString); - } - } - String trimString = getAttributeOrNull(icon, ATTR_TRIM); - if (trimString != null) { - mIconState.trim = Boolean.valueOf(trimString); - } - String paddingString = getAttributeOrNull(icon, ATTR_PADDING); - if (paddingString != null) { - mIconState.padding = Integer.parseInt(paddingString); - } - String sourceTypeString = getAttributeOrNull(icon, ATTR_SOURCE_TYPE); - if (sourceTypeString != null) { - sourceTypeString = sourceTypeString.toUpperCase(Locale.US); - boolean found = false; - for (SourceType type : SourceType.values()) { - if (sourceTypeString.equals(type.name())) { - mIconState.sourceType = type; - found = true; - break; - } - } - if (!found) { - AdtPlugin.log(null, "Unknown source type %1$s", sourceTypeString); - } - } - mIconState.clipartName = getAttributeOrNull(icon, ATTR_CLIPART_NAME); - - String textString = getAttributeOrNull(icon, ATTR_TEXT); - if (textString != null) { - mIconState.text = textString; - } - } - - return mIconState; - } - - void updateIconName(List<Parameter> parameters, StringEvaluator evaluator) { - if (mIconState != null) { - NodeList icons = mDocument.getElementsByTagName(TAG_ICONS); - if (icons.getLength() < 1) { - return; - } - Element icon = (Element) icons.item(0); - String name = getAttributeOrNull(icon, ATTR_NAME); - if (name != null) { - mIconState.outputName = evaluator.evaluate(name, parameters); - } - } - } - - private static RGB getRgb(@NonNull Element element, @NonNull String name) { - String colorString = getAttributeOrNull(element, name); - if (colorString != null) { - int rgb = ImageUtils.getColor(colorString.trim()); - return ImageUtils.intToRgb(rgb); - } - - return null; - } - - @Nullable - private static String getAttributeOrNull(@NonNull Element element, @NonNull String name) { - String value = element.getAttribute(name); - if (value != null && value.isEmpty()) { - return null; - } - return value; - } - - @Nullable - String getThumbnailPath() { - // Apply selector logic. Pick the thumb first thumb that satisfies the largest number - // of conditions. - NodeList thumbs = mDocument.getElementsByTagName(TAG_THUMB); - if (thumbs.getLength() == 0) { - return null; - } - - - int bestMatchCount = 0; - Element bestMatch = null; - - for (int i = 0, n = thumbs.getLength(); i < n; i++) { - Element thumb = (Element) thumbs.item(i); - - NamedNodeMap attributes = thumb.getAttributes(); - if (bestMatch == null && attributes.getLength() == 0) { - bestMatch = thumb; - } else if (attributes.getLength() <= bestMatchCount) { - // Already have a match with this number of attributes, no point checking - continue; - } else { - boolean match = true; - for (int j = 0, max = attributes.getLength(); j < max; j++) { - Attr attribute = (Attr) attributes.item(j); - Parameter parameter = mParameterMap.get(attribute.getName()); - if (parameter == null) { - AdtPlugin.log(null, "Unexpected parameter in template thumbnail: %1$s", - attribute.getName()); - continue; - } - String thumbNailValue = attribute.getValue(); - String editedValue = parameter.value != null ? parameter.value.toString() : ""; - if (!thumbNailValue.equals(editedValue)) { - match = false; - break; - } - } - if (match) { - bestMatch = thumb; - bestMatchCount = attributes.getLength(); - } - } - } - - if (bestMatch != null) { - NodeList children = bestMatch.getChildNodes(); - for (int i = 0, n = children.getLength(); i < n; i++) { - Node child = children.item(i); - if (child.getNodeType() == Node.TEXT_NODE) { - return child.getNodeValue().trim(); - } - } - } - - return null; - } - - /** - * Returns the dependencies (as a list of pairs of names and revisions) - * required by this template - */ - List<Pair<String, Integer>> getDependencies() { - if (mDependencies == null) { - NodeList elements = mDocument.getElementsByTagName(TAG_DEPENDENCY); - if (elements.getLength() == 0) { - return Collections.emptyList(); - } - - List<Pair<String, Integer>> dependencies = Lists.newArrayList(); - for (int i = 0, n = elements.getLength(); i < n; i++) { - Element element = (Element) elements.item(i); - String name = element.getAttribute(ATTR_NAME); - int revision = -1; - String revisionString = element.getAttribute(ATTR_REVISION); - if (!revisionString.isEmpty()) { - revision = Integer.parseInt(revisionString); - } - dependencies.add(Pair.of(name, revision)); - } - mDependencies = dependencies; - } - - return mDependencies; - } - - /** Returns the list of available parameters */ - @NonNull - List<Parameter> getParameters() { - return mParameters; - } - - /** - * Returns the parameter of the given id, or null if not found - * - * @param id the id of the target parameter - * @return the corresponding parameter, or null if not found - */ - @Nullable - public Parameter getParameter(@NonNull String id) { - for (Parameter parameter : mParameters) { - if (id.equals(parameter.id)) { - return parameter; - } - } - - return null; - } - - /** Returns a default icon for templates */ - static Image getDefaultTemplateIcon() { - return IconFactory.getInstance().getIcon("default_template"); //$NON-NLS-1$ - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplatePreviewPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplatePreviewPage.java deleted file mode 100644 index c3d28fcf2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplatePreviewPage.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.ltk.internal.ui.refactoring.PreviewWizardPage; - -import java.util.List; - -@SuppressWarnings("restriction") // Refactoring UI -class TemplatePreviewPage extends PreviewWizardPage { - private final NewTemplateWizardState mValues; - - TemplatePreviewPage(NewTemplateWizardState values) { - super(true); - mValues = values; - setTitle("Preview"); - setDescription("Optionally review pending changes"); - } - - @Override - public void setVisible(boolean visible) { - if (visible) { - List<Change> changes = mValues.computeChanges(); - CompositeChange root = new CompositeChange("Create template", - changes.toArray(new Change[changes.size()])); - setChange(root); - } - - super.setVisible(visible); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestPage.java deleted file mode 100644 index e461d5597..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestPage.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.DirectoryDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -import java.io.File; - -/** For template developers: Test local template directory */ -public class TemplateTestPage extends WizardPage - implements SelectionListener, ModifyListener { - private Text mLocation; - private Button mButton; - private static String sLocation; // Persist between repeated invocations - private Button mProjectToggle; - private File mTemplate; - - TemplateTestPage() { - super("testWizardPage"); //$NON-NLS-1$ - setTitle("Wizard Tester"); - setDescription("Test a new template"); - } - - @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - container.setLayout(new GridLayout(3, false)); - - Label label = new Label(container, SWT.NONE); - label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - label.setText("Template Location:"); - - mLocation = new Text(container, SWT.BORDER); - GridData gd_mLocation = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); - gd_mLocation.widthHint = 400; - mLocation.setLayoutData(gd_mLocation); - if (sLocation != null) { - mLocation.setText(sLocation); - } - mLocation.addModifyListener(this); - - mButton = new Button(container, SWT.FLAT); - mButton.setText("..."); - - mProjectToggle = new Button(container, SWT.CHECK); - mProjectToggle.setEnabled(false); - mProjectToggle.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); - mProjectToggle.setText("Full project template"); - new Label(container, SWT.NONE); - mButton.addSelectionListener(this); - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - validatePage(); - } - - private boolean validatePage() { - String error = null; - - String path = mLocation.getText().trim(); - if (path == null || path.length() == 0) { - error = "Select a template directory"; - mTemplate = null; - } else { - mTemplate = new File(path); - if (!mTemplate.exists()) { - error = String.format("%1$s does not exist", path); - } else { - // Preserve across wizard sessions - sLocation = path; - - if (mTemplate.isDirectory()) { - if (!new File(mTemplate, TemplateHandler.TEMPLATE_XML).exists()) { - error = String.format("Not a template: missing template.xml file in %1$s ", - path); - } - } else { - if (mTemplate.getName().equals(TemplateHandler.TEMPLATE_XML)) { - mTemplate = mTemplate.getParentFile(); - } else { - error = String.format("Select a directory containing a template"); - } - } - } - } - - setPageComplete(error == null); - if (error != null) { - setMessage(error, IMessageProvider.ERROR); - } else { - setErrorMessage(null); - setMessage(null); - } - - return error == null; - } - - @Override - public void modifyText(ModifyEvent e) { - validatePage(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - if (e.getSource() == mButton) { - DirectoryDialog dialog = new DirectoryDialog(mButton.getShell(), SWT.OPEN); - String path = mLocation.getText().trim(); - if (path.length() > 0) { - dialog.setFilterPath(path); - } - String file = dialog.open(); - if (file != null) { - mLocation.setText(file); - } - } - - validatePage(); - } - - File getLocation() { - return mTemplate; - } - - boolean isProjectTemplate() { - return mProjectToggle.getSelection(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestWizard.java deleted file mode 100644 index b3b1ef2f4..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestWizard.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.ui.IWorkbench; - -import java.io.File; - -/** - * Template wizard which creates parameterized templates - */ -public class TemplateTestWizard extends NewTemplateWizard { - private TemplateTestPage mSelectionPage; - private IProject mProject; - - /** Creates a new wizard for testing template definitions in a local directory */ - public TemplateTestWizard() { - super(""); - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - super.init(workbench, selection); - if (mValues != null) { - mProject = mValues.project; - } - - mMainPage = null; - mValues = null; - - mSelectionPage = new TemplateTestPage(); - } - - @Override - public void addPages() { - addPage(mSelectionPage); - } - - @Override - public IWizardPage getNextPage(IWizardPage page) { - if (page == mSelectionPage) { - File file = mSelectionPage.getLocation(); - if (file != null && file.exists()) { - if (mValues == null) { - mValues = new NewTemplateWizardState(); - mValues.setTemplateLocation(file); - mValues.project = mProject; - hideBuiltinParameters(); - - mMainPage = new NewTemplatePage(mValues, true); - addPage(mMainPage); - } else { - mValues.setTemplateLocation(file); - } - - return mMainPage; - } - } - - return super.getNextPage(page); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateWizard.java deleted file mode 100644 index 7ca32f91f..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateWizard.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import static org.eclipse.core.resources.IResource.DEPTH_INFINITE; - -import com.android.annotations.NonNull; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.assetstudio.ConfigureAssetSetPage; -import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.google.common.collect.Lists; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.INewWizard; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.swing.SwingUtilities; - -abstract class TemplateWizard extends Wizard implements INewWizard { - private static final String PROJECT_LOGO_LARGE = "android-64"; //$NON-NLS-1$ - protected IWorkbench mWorkbench; - private UpdateToolsPage mUpdatePage; - private InstallDependencyPage mDependencyPage; - private TemplatePreviewPage mPreviewPage; - protected ConfigureAssetSetPage mIconPage; - - protected TemplateWizard() { - } - - /** Should this wizard add an icon page? */ - protected boolean shouldAddIconPage() { - return false; - } - - @Override - public void init(IWorkbench workbench, IStructuredSelection selection) { - mWorkbench = workbench; - - setHelpAvailable(false); - ImageDescriptor desc = IconFactory.getInstance().getImageDescriptor(PROJECT_LOGO_LARGE); - setDefaultPageImageDescriptor(desc); - - if (!UpdateToolsPage.isUpToDate()) { - mUpdatePage = new UpdateToolsPage(); - } - - setNeedsProgressMonitor(true); - - // Trigger a check to see if the SDK needs to be reloaded (which will - // invoke onSdkLoaded asynchronously as needed). - AdtPlugin.getDefault().refreshSdk(); - } - - @Override - public void addPages() { - super.addPages(); - if (mUpdatePage != null) { - addPage(mUpdatePage); - } - } - - @Override - public IWizardPage getStartingPage() { - if (mUpdatePage != null && mUpdatePage.isPageComplete()) { - return getNextPage(mUpdatePage); - } - - return super.getStartingPage(); - } - - protected WizardPage getPreviewPage(NewTemplateWizardState values) { - if (mPreviewPage == null) { - mPreviewPage = new TemplatePreviewPage(values); - addPage(mPreviewPage); - } - - return mPreviewPage; - } - - protected WizardPage getIconPage(CreateAssetSetWizardState iconState) { - if (mIconPage == null) { - mIconPage = new ConfigureAssetSetPage(iconState); - mIconPage.setTitle("Configure Icon"); - addPage(mIconPage); - } - - return mIconPage; - } - - protected WizardPage getDependencyPage(TemplateMetadata template, boolean create) { - if (!create) { - return mDependencyPage; - } - - if (mDependencyPage == null) { - mDependencyPage = new InstallDependencyPage(); - addPage(mDependencyPage); - } - mDependencyPage.setTemplate(template); - return mDependencyPage; - } - - /** - * Returns the project where the template is being inserted - * - * @return the project to insert the template into - */ - @NonNull - protected abstract IProject getProject(); - - /** - * Returns the list of files to open, which might be empty. This method will - * only be called <b>after</b> {@link #computeChanges()} has been called. - * - * @return a list of files to open - */ - @NonNull - protected abstract List<String> getFilesToOpen(); - - /** - * Returns the list of files to open, which might be empty. This method will - * only be called <b>after</b> {@link #computeChanges()} has been called. - * - * @return a list of files to open - */ - @NonNull - protected abstract List<Runnable> getFinalizingActions(); - - /** - * Computes the changes to the {@link #getProject()} this template should - * perform - * - * @return the changes to perform - */ - protected abstract List<Change> computeChanges(); - - protected boolean performFinish(IProgressMonitor monitor) throws InvocationTargetException { - List<Change> changes = computeChanges(); - if (!changes.isEmpty()) { - monitor.beginTask("Creating template...", changes.size()); - try { - CompositeChange composite = new CompositeChange("", - changes.toArray(new Change[changes.size()])); - composite.perform(monitor); - } catch (CoreException e) { - AdtPlugin.log(e, null); - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - - // TBD: Is this necessary now that we're using IFile objects? - try { - getProject().refreshLocal(DEPTH_INFINITE, new NullProgressMonitor()); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - return true; - } - - @Override - public boolean performFinish() { - final AtomicBoolean success = new AtomicBoolean(); - try { - getContainer().run(true, false, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, - InterruptedException { - boolean ok = performFinish(monitor); - success.set(ok); - } - }); - - } catch (InvocationTargetException e) { - AdtPlugin.log(e, null); - return false; - } catch (InterruptedException e) { - AdtPlugin.log(e, null); - return false; - } - - if (success.get()) { - // Open the primary file/files - NewTemplateWizard.openFiles(getProject(), getFilesToOpen(), mWorkbench); - return true; - } else { - return false; - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TypedVariable.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TypedVariable.java deleted file mode 100644 index 468a10c77..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TypedVariable.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import java.util.Locale; - -import org.xml.sax.Attributes; - -public class TypedVariable { - public enum Type { - STRING, - BOOLEAN, - INTEGER; - - public static Type get(String name) { - if (name == null) { - return STRING; - } - try { - return valueOf(name.toUpperCase(Locale.US)); - } catch (IllegalArgumentException e) { - System.err.println("Unexpected global type '" + name + "'"); - System.err.println("Expected one of :"); - for (Type s : Type.values()) { - System.err.println(" " + s.name().toLowerCase(Locale.US)); - } - } - - return STRING; - } - } - - public static Object parseGlobal(Attributes attributes) { - String value = attributes.getValue(TemplateHandler.ATTR_VALUE); - Type type = Type.get(attributes.getValue(TemplateHandler.ATTR_TYPE)); - - switch (type) { - case STRING: - return value; - case BOOLEAN: - return Boolean.parseBoolean(value); - case INTEGER: - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return value; - } - } - - return value; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/UpdateToolsPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/UpdateToolsPage.java deleted file mode 100644 index 5bbf449d4..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/UpdateToolsPage.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.ide.eclipse.adt.internal.wizards.templates; - -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -class UpdateToolsPage extends WizardPage implements SelectionListener { - private Button mInstallButton; - UpdateToolsPage() { - super("update"); - setTitle("Update Tools"); - validatePage(); - } - - @Override - public void createControl(Composite parent) { - Composite container = new Composite(parent, SWT.NULL); - setControl(container); - container.setLayout(new GridLayout(1, false)); - - Label label = new Label(container, SWT.WRAP); - GridData layoutData = new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1); - layoutData.widthHint = NewTemplatePage.WIZARD_PAGE_WIDTH - 50; - label.setLayoutData(layoutData); - label.setText( - "Your tools installation appears to be out of date (or not yet installed).\n" + - "\n" + - "This wizard depends on templates distributed with the Android SDK Tools.\n" + - "\n" + - "Please update the tools first (via Window > Android SDK Manager, or by " + - "using the \"android\" command in a terminal window). Note that on Windows " + - "you may need to restart the IDE, since there are some known problems where " + - "Windows locks the files held open by the running IDE, so the updater is " + - "unable to delete them in order to upgrade them."); - - mInstallButton = new Button(container, SWT.NONE); - mInstallButton.setText("Check Again"); - mInstallButton.addSelectionListener(this); - } - - @Override - public boolean isPageComplete() { - return isUpToDate(); - } - - static boolean isUpToDate() { - return TemplateManager.getTemplateRootFolder() != null; - } - - private void validatePage() { - boolean ok = isUpToDate(); - setPageComplete(ok); - if (ok) { - setErrorMessage(null); - setMessage(null); - } else { - setErrorMessage("The tools need to be updated via the SDK Manager"); - } - } - - // ---- Implements SelectionListener ---- - - @Override - public void widgetSelected(SelectionEvent e) { - if (e.getSource() == mInstallButton) { - validatePage(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } -} |