aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java326
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/CreateFileChange.java107
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmActivityToLayoutMethod.java64
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmCamelCaseToUnderscoreMethod.java38
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmClassNameToResourceMethod.java67
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlAttributeMethod.java40
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlStringMethod.java43
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmEscapeXmlTextMethod.java40
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmExtractLettersMethod.java45
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmLayoutToActivityMethod.java61
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmSlashedPackageNameMethod.java39
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/FmUnderscoreToCamelCaseMethod.java39
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java298
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java187
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java931
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java456
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizardState.java125
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java946
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java212
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizardState.java215
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/Parameter.java417
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ProjectContentsPage.java380
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/StringEvaluator.java101
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java1239
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateManager.java261
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java468
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplatePreviewPage.java46
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestPage.java161
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateTestWizard.java78
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateWizard.java222
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TypedVariable.java50
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/UpdateToolsPage.java94
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
- * &lt; and &amp; 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) {
- }
-}