aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java85
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java94
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java36
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java34
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java36
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java183
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java626
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java378
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java339
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java268
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java264
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java291
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java642
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ConfirmationPage.java275
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.java43
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.properties27
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportStatus.java56
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/FinalPage.java112
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleExportWizard.java111
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleModule.java90
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ImportInsteadPage.java55
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java275
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSetupBuilder.java425
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java809
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/FileStoreAdapter.java160
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java512
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportProjectWizard.java94
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportedProject.java256
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java1520
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java181
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java412
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewSampleProjectWizard.java32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java606
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SampleSelectionPage.java271
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SdkSelectionPage.java487
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/TestTargetPage.java293
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetGroup.java109
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetHelper.java130
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/AddTranslationDialog.java653
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java282
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java1163
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java431
-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
75 files changed, 0 insertions, 20974 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java
deleted file mode 100644
index 4d3870b86..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2007 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.actions;
-
-import com.android.ide.eclipse.adt.internal.lint.EclipseLintRunner;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-public class ExportAction implements IObjectActionDelegate {
-
- private ISelection mSelection;
- private Shell mShell;
-
- /**
- * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
- */
- @Override
- public void setActivePart(IAction action, IWorkbenchPart targetPart) {
- mShell = targetPart.getSite().getShell();
- }
-
- @Override
- public void run(IAction action) {
- if (mSelection instanceof IStructuredSelection) {
- IStructuredSelection selection = (IStructuredSelection)mSelection;
- // get the unique selected item.
- if (selection.size() == 1) {
- Object element = selection.getFirstElement();
-
- // get the project object from it.
- IProject project = null;
- if (element instanceof IProject) {
- project = (IProject) element;
- } else if (element instanceof IAdaptable) {
- project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
- }
-
- // and finally do the action
- if (project != null) {
- if (!EclipseLintRunner.runLintOnExport(mShell, project)) {
- return;
- }
-
- ProjectState state = Sdk.getProjectState(project);
- if (state.isLibrary()) {
- MessageDialog.openError(mShell, "Android Export",
- "Android library projects cannot be exported.");
- } else {
- ExportHelper.exportUnsignedReleaseApk(project);
- }
- }
- }
- }
- }
-
- @Override
- public void selectionChanged(IAction action, ISelection selection) {
- mSelection = selection;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java
deleted file mode 100644
index 673d9569f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2008 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.actions;
-
-import com.android.ide.eclipse.adt.internal.lint.EclipseLintRunner;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPart;
-
-public class ExportWizardAction implements IObjectActionDelegate {
-
- private ISelection mSelection;
- private IWorkbench mWorkbench;
-
- /**
- * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
- */
- @Override
- public void setActivePart(IAction action, IWorkbenchPart targetPart) {
- mWorkbench = targetPart.getSite().getWorkbenchWindow().getWorkbench();
- }
-
- @Override
- public void run(IAction action) {
- if (mSelection instanceof IStructuredSelection) {
- IStructuredSelection selection = (IStructuredSelection)mSelection;
-
- // get the unique selected item.
- if (selection.size() == 1) {
- Object element = selection.getFirstElement();
-
- // get the project object from it.
- IProject project = null;
- if (element instanceof IProject) {
- project = (IProject) element;
- } else if (element instanceof IAdaptable) {
- project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
- }
-
- // and finally do the action
- if (project != null) {
- if (!EclipseLintRunner.runLintOnExport(
- mWorkbench.getActiveWorkbenchWindow().getShell(), project)) {
- return;
- }
-
- ProjectState state = Sdk.getProjectState(project);
- if (state.isLibrary()) {
- MessageDialog.openError(mWorkbench.getDisplay().getActiveShell(),
- "Android Export",
- "Android library projects cannot be exported.");
- } else {
- // call the export wizard on the current selection.
- ExportWizard wizard = new ExportWizard();
- wizard.init(mWorkbench, selection);
- WizardDialog dialog = new WizardDialog(
- mWorkbench.getDisplay().getActiveShell(), wizard);
- dialog.open();
- }
- }
- }
- }
- }
-
- @Override
- public void selectionChanged(IAction action, ISelection selection) {
- mSelection = selection;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java
deleted file mode 100644
index 38f4768b1..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 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.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Project".
- * It displays the Android New Project wizard to create a new Android Project (not a test project).
- *
- * @see NewTestProjectAction
- */
-public class NewProjectAction extends OpenWizardAction {
-
- @Override
- protected IWorkbenchWizard instanciateWizard(IAction action) {
- return new NewProjectWizard();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java
deleted file mode 100755
index c8e45ef1a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2009 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.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Test Project".
- * It displays the Android New Project wizard to create a new Test Project.
- */
-public class NewTestProjectAction extends OpenWizardAction {
-
- @Override
- protected IWorkbenchWizard instanciateWizard(IAction action) {
- return new NewTestProjectWizard();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java
deleted file mode 100644
index ba349c30a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 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.actions;
-
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Project" or for the
- * project > Android Project context menu.
- *
- * It displays the Android New XML file wizard.
- */
-public class NewXmlFileAction extends OpenWizardAction {
-
- @Override
- protected IWorkbenchWizard instanciateWizard(IAction action) {
- return new NewXmlFileWizard();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java
deleted file mode 100644
index a3e6135e5..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2009 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.actions;
-
-import com.android.ide.eclipse.adt.internal.ui.IUpdateWizardDialog;
-import com.android.ide.eclipse.adt.internal.ui.WizardDialogEx;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.IWorkbenchWizard;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
-import org.eclipse.ui.internal.LegacyResourceSupport;
-import org.eclipse.ui.internal.actions.NewWizardShortcutAction;
-import org.eclipse.ui.internal.util.Util;
-
-/**
- * An abstract action that displays one of our wizards.
- * Derived classes must provide the actual wizard to display.
- */
-/*package*/ abstract class OpenWizardAction
- implements IWorkbenchWindowActionDelegate, IObjectActionDelegate {
-
- /**
- * The wizard dialog width, extracted from {@link NewWizardShortcutAction}
- */
- private static final int SIZING_WIZARD_WIDTH = 500;
-
- /**
- * The wizard dialog height, extracted from {@link NewWizardShortcutAction}
- */
- private static final int SIZING_WIZARD_HEIGHT = 500;
-
- /** The wizard that was created by {@link #run(IAction)}. */
- private IWorkbenchWizard mWizard;
- /** The result from the dialog */
- private int mDialogResult;
-
- private ISelection mSelection;
- private IWorkbench mWorkbench;
-
- /** Returns the wizard that was created by {@link #run(IAction)}. */
- public IWorkbenchWizard getWizard() {
- return mWizard;
- }
-
- /** Returns the result from {@link Dialog#open()}, available after
- * the completion of {@link #run(IAction)}. */
- public int getDialogResult() {
- return mDialogResult;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
- */
- @Override
- public void dispose() {
- // pass
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
- */
- @Override
- public void init(IWorkbenchWindow window) {
- // pass
- }
-
- /**
- * Opens and display the Android New Project Wizard.
- * <p/>
- * Most of this implementation is extracted from {@link NewWizardShortcutAction#run()}.
- *
- * @param action The action that got us here. Can be null when used internally.
- * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
- */
- @Override
- public void run(IAction action) {
-
- // get the workbench and the current window
- IWorkbench workbench = mWorkbench != null ? mWorkbench : PlatformUI.getWorkbench();
- IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-
- // This code from NewWizardShortcutAction#run() gets the current window selection
- // and converts it to a workbench structured selection for the wizard, if possible.
- ISelection selection = mSelection;
- if (selection == null) {
- selection = window.getSelectionService().getSelection();
- }
-
- IStructuredSelection selectionToPass = StructuredSelection.EMPTY;
- if (selection instanceof IStructuredSelection) {
- selectionToPass = (IStructuredSelection) selection;
- } else {
- // Build the selection from the IFile of the editor
- IWorkbenchPart part = window.getPartService().getActivePart();
- if (part instanceof IEditorPart) {
- IEditorInput input = ((IEditorPart) part).getEditorInput();
- Class<?> fileClass = LegacyResourceSupport.getFileClass();
- if (input != null && fileClass != null) {
- Object file = Util.getAdapter(input, fileClass);
- if (file != null) {
- selectionToPass = new StructuredSelection(file);
- }
- }
- }
- }
-
- // Create the wizard and initialize it with the selection
- mWizard = instanciateWizard(action);
- mWizard.init(workbench, selectionToPass);
-
- // It's not visible yet until a dialog is created and opened
- Shell parent = window.getShell();
- WizardDialogEx dialog = new WizardDialogEx(parent, mWizard);
- dialog.create();
-
- if (mWizard instanceof IUpdateWizardDialog) {
- ((IUpdateWizardDialog) mWizard).updateWizardDialog(dialog);
- }
-
- // This code comes straight from NewWizardShortcutAction#run()
- Point defaultSize = dialog.getShell().getSize();
- dialog.getShell().setSize(
- Math.max(SIZING_WIZARD_WIDTH, defaultSize.x),
- Math.max(SIZING_WIZARD_HEIGHT, defaultSize.y));
- window.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),
- IWorkbenchHelpContextIds.NEW_WIZARD_SHORTCUT);
-
- mDialogResult = dialog.open();
- }
-
- /**
- * Called by {@link #run(IAction)} to instantiate the actual wizard.
- *
- * @param action The action parameter from {@link #run(IAction)}.
- * This can be null.
- * @return A new wizard instance. Must not be null.
- */
- protected abstract IWorkbenchWizard instanciateWizard(IAction action);
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
- */
- @Override
- public void selectionChanged(IAction action, ISelection selection) {
- mSelection = selection;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
- */
- @Override
- public void setActivePart(IAction action, IWorkbenchPart targetPart) {
- mWorkbench = targetPart.getSite().getWorkbenchWindow().getWorkbench();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
deleted file mode 100644
index 170da6d33..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.annotations.Nullable;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.utils.FingerprintUtils;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.BuildToolInfo.PathId;
-import com.android.sdklib.internal.build.DebugKeyProvider.IKeyGenOutput;
-import com.android.sdklib.internal.build.KeystoreHelper;
-import com.android.utils.GrabProcessOutput;
-import com.android.utils.GrabProcessOutput.IProcessOutput;
-import com.android.utils.GrabProcessOutput.Wait;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IExportWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Export wizard to export an apk signed with a release key/certificate.
- */
-public final class ExportWizard extends Wizard implements IExportWizard {
-
- private static final String PROJECT_LOGO_LARGE = "icons/android-64.png"; //$NON-NLS-1$
-
- private static final String PAGE_PROJECT_CHECK = "Page_ProjectCheck"; //$NON-NLS-1$
- private static final String PAGE_KEYSTORE_SELECTION = "Page_KeystoreSelection"; //$NON-NLS-1$
- private static final String PAGE_KEY_CREATION = "Page_KeyCreation"; //$NON-NLS-1$
- private static final String PAGE_KEY_SELECTION = "Page_KeySelection"; //$NON-NLS-1$
- private static final String PAGE_KEY_CHECK = "Page_KeyCheck"; //$NON-NLS-1$
-
- static final String PROPERTY_KEYSTORE = "keystore"; //$NON-NLS-1$
- static final String PROPERTY_ALIAS = "alias"; //$NON-NLS-1$
- static final String PROPERTY_DESTINATION = "destination"; //$NON-NLS-1$
-
- static final int APK_FILE_SOURCE = 0;
- static final int APK_FILE_DEST = 1;
- static final int APK_COUNT = 2;
-
- /**
- * Base page class for the ExportWizard page. This class add the {@link #onShow()} callback.
- */
- static abstract class ExportWizardPage extends WizardPage {
-
- /** bit mask constant for project data change event */
- protected static final int DATA_PROJECT = 0x001;
- /** bit mask constant for keystore data change event */
- protected static final int DATA_KEYSTORE = 0x002;
- /** bit mask constant for key data change event */
- protected static final int DATA_KEY = 0x004;
-
- protected static final VerifyListener sPasswordVerifier = new VerifyListener() {
- @Override
- public void verifyText(VerifyEvent e) {
- // verify the characters are valid for password.
- int len = e.text.length();
-
- // first limit to 127 characters max
- if (len + ((Text)e.getSource()).getText().length() > 127) {
- e.doit = false;
- return;
- }
-
- // now only take non control characters
- for (int i = 0 ; i < len ; i++) {
- if (e.text.charAt(i) < 32) {
- e.doit = false;
- return;
- }
- }
- }
- };
-
- /**
- * Bit mask indicating what changed while the page was hidden.
- * @see #DATA_PROJECT
- * @see #DATA_KEYSTORE
- * @see #DATA_KEY
- */
- protected int mProjectDataChanged = 0;
-
- ExportWizardPage(String name) {
- super(name);
- }
-
- abstract void onShow();
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- onShow();
- mProjectDataChanged = 0;
- }
- }
-
- final void projectDataChanged(int changeMask) {
- mProjectDataChanged |= changeMask;
- }
-
- /**
- * Calls {@link #setErrorMessage(String)} and {@link #setPageComplete(boolean)} based on a
- * {@link Throwable} object.
- */
- protected void onException(Throwable t) {
- String message = getExceptionMessage(t);
-
- setErrorMessage(message);
- setPageComplete(false);
- }
- }
-
- private ExportWizardPage mPages[] = new ExportWizardPage[5];
-
- private IProject mProject;
-
- private String mKeystore;
- private String mKeystorePassword;
- private boolean mKeystoreCreationMode;
-
- private String mKeyAlias;
- private String mKeyPassword;
- private int mValidity;
- private String mDName;
-
- private PrivateKey mPrivateKey;
- private X509Certificate mCertificate;
-
- private File mDestinationFile;
-
- private ExportWizardPage mKeystoreSelectionPage;
- private ExportWizardPage mKeyCreationPage;
- private ExportWizardPage mKeySelectionPage;
- private ExportWizardPage mKeyCheckPage;
-
- private boolean mKeyCreationMode;
-
- private List<String> mExistingAliases;
-
- public ExportWizard() {
- setHelpAvailable(false); // TODO have help
- setWindowTitle("Export Android Application");
- setImageDescriptor();
- }
-
- @Override
- public void addPages() {
- addPage(mPages[0] = new ProjectCheckPage(this, PAGE_PROJECT_CHECK));
- addPage(mKeystoreSelectionPage = mPages[1] = new KeystoreSelectionPage(this,
- PAGE_KEYSTORE_SELECTION));
- addPage(mKeyCreationPage = mPages[2] = new KeyCreationPage(this, PAGE_KEY_CREATION));
- addPage(mKeySelectionPage = mPages[3] = new KeySelectionPage(this, PAGE_KEY_SELECTION));
- addPage(mKeyCheckPage = mPages[4] = new KeyCheckPage(this, PAGE_KEY_CHECK));
- }
-
- @Override
- public boolean performFinish() {
- // save the properties
- ProjectHelper.saveStringProperty(mProject, PROPERTY_KEYSTORE, mKeystore);
- ProjectHelper.saveStringProperty(mProject, PROPERTY_ALIAS, mKeyAlias);
- ProjectHelper.saveStringProperty(mProject, PROPERTY_DESTINATION,
- mDestinationFile.getAbsolutePath());
-
- // run the export in an UI runnable.
- IWorkbench workbench = PlatformUI.getWorkbench();
- final boolean[] result = new boolean[1];
- try {
- workbench.getProgressService().busyCursorWhile(new IRunnableWithProgress() {
- /**
- * Run the export.
- * @throws InvocationTargetException
- * @throws InterruptedException
- */
- @Override
- public void run(IProgressMonitor monitor) throws InvocationTargetException,
- InterruptedException {
- try {
- result[0] = doExport(monitor);
- } finally {
- monitor.done();
- }
- }
- });
- } catch (InvocationTargetException e) {
- return false;
- } catch (InterruptedException e) {
- return false;
- }
-
- return result[0];
- }
-
- private boolean doExport(IProgressMonitor monitor) {
- try {
- // if needed, create the keystore and/or key.
- if (mKeystoreCreationMode || mKeyCreationMode) {
- final ArrayList<String> output = new ArrayList<String>();
- boolean createdStore = KeystoreHelper.createNewStore(
- mKeystore,
- null /*storeType*/,
- mKeystorePassword,
- mKeyAlias,
- mKeyPassword,
- mDName,
- mValidity,
- new IKeyGenOutput() {
- @Override
- public void err(String message) {
- output.add(message);
- }
- @Override
- public void out(String message) {
- output.add(message);
- }
- });
-
- if (createdStore == false) {
- // keystore creation error!
- displayError(output.toArray(new String[output.size()]));
- return false;
- }
-
- // keystore is created, now load the private key and certificate.
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream fis = new FileInputStream(mKeystore);
- keyStore.load(fis, mKeystorePassword.toCharArray());
- fis.close();
- PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
- mKeyAlias, new KeyStore.PasswordProtection(mKeyPassword.toCharArray()));
-
- if (entry != null) {
- mPrivateKey = entry.getPrivateKey();
- mCertificate = (X509Certificate)entry.getCertificate();
-
- AdtPlugin.printToConsole(mProject,
- String.format("New keystore %s has been created.",
- mDestinationFile.getAbsolutePath()),
- "Certificate fingerprints:",
- String.format(" MD5 : %s", getCertMd5Fingerprint()),
- String.format(" SHA1: %s", getCertSha1Fingerprint()));
-
- } else {
- // this really shouldn't happen since we now let the user choose the key
- // from a list read from the store.
- displayError("Could not find key");
- return false;
- }
- }
-
- // check the private key/certificate again since it may have been created just above.
- if (mPrivateKey != null && mCertificate != null) {
- // check whether we can run zipalign.
- boolean runZipAlign = false;
-
- ProjectState projectState = Sdk.getProjectState(mProject);
- BuildToolInfo buildToolInfo = ExportHelper.getBuildTools(projectState);
-
- String zipAlignPath = buildToolInfo.getPath(PathId.ZIP_ALIGN);
- runZipAlign = zipAlignPath != null && new File(zipAlignPath).isFile();
-
- File apkExportFile = mDestinationFile;
- if (runZipAlign) {
- // create a temp file for the original export.
- apkExportFile = File.createTempFile("androidExport_", ".apk");
- }
-
- // export the signed apk.
- ExportHelper.exportReleaseApk(mProject, apkExportFile,
- mPrivateKey, mCertificate, monitor);
-
- // align if we can
- if (runZipAlign) {
- String message = zipAlign(zipAlignPath, apkExportFile, mDestinationFile);
- if (message != null) {
- displayError(message);
- return false;
- }
- } else {
- AdtPlugin.displayWarning("Export Wizard",
- "The zipalign tool was not found in the SDK.\n\n" +
- "Please update to the latest SDK and re-export your application\n" +
- "or run zipalign manually.\n\n" +
- "Aligning applications allows Android to use application resources\n" +
- "more efficiently.");
- }
-
- return true;
- }
- } catch (Throwable t) {
- displayError(t);
- }
-
- return false;
- }
-
- @Override
- public boolean canFinish() {
- // check if we have the apk to resign, the destination location, and either
- // a private key/certificate or the creation mode. In creation mode, unless
- // all the key/keystore info is valid, the user cannot reach the last page, so there's
- // no need to check them again here.
- return ((mPrivateKey != null && mCertificate != null)
- || mKeystoreCreationMode || mKeyCreationMode) &&
- mDestinationFile != null;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench,
- * org.eclipse.jface.viewers.IStructuredSelection)
- */
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- // get the project from the selection
- Object selected = selection.getFirstElement();
-
- if (selected instanceof IProject) {
- mProject = (IProject)selected;
- } else if (selected instanceof IAdaptable) {
- IResource r = (IResource)((IAdaptable)selected).getAdapter(IResource.class);
- if (r != null) {
- mProject = r.getProject();
- }
- }
- }
-
- ExportWizardPage getKeystoreSelectionPage() {
- return mKeystoreSelectionPage;
- }
-
- ExportWizardPage getKeyCreationPage() {
- return mKeyCreationPage;
- }
-
- ExportWizardPage getKeySelectionPage() {
- return mKeySelectionPage;
- }
-
- ExportWizardPage getKeyCheckPage() {
- return mKeyCheckPage;
- }
-
- /**
- * Returns an image descriptor for the wizard logo.
- */
- private void setImageDescriptor() {
- ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
- setDefaultPageImageDescriptor(desc);
- }
-
- IProject getProject() {
- return mProject;
- }
-
- void setProject(IProject project) {
- mProject = project;
-
- updatePageOnChange(ExportWizardPage.DATA_PROJECT);
- }
-
- void setKeystore(String path) {
- mKeystore = path;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- String getKeystore() {
- return mKeystore;
- }
-
- void setKeystoreCreationMode(boolean createStore) {
- mKeystoreCreationMode = createStore;
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- boolean getKeystoreCreationMode() {
- return mKeystoreCreationMode;
- }
-
-
- void setKeystorePassword(String password) {
- mKeystorePassword = password;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- String getKeystorePassword() {
- return mKeystorePassword;
- }
-
- void setKeyCreationMode(boolean createKey) {
- mKeyCreationMode = createKey;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- boolean getKeyCreationMode() {
- return mKeyCreationMode;
- }
-
- void setExistingAliases(List<String> aliases) {
- mExistingAliases = aliases;
- }
-
- List<String> getExistingAliases() {
- return mExistingAliases;
- }
-
- void setKeyAlias(String name) {
- mKeyAlias = name;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getKeyAlias() {
- return mKeyAlias;
- }
-
- void setKeyPassword(String password) {
- mKeyPassword = password;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getKeyPassword() {
- return mKeyPassword;
- }
-
- void setValidity(int validity) {
- mValidity = validity;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- int getValidity() {
- return mValidity;
- }
-
- void setDName(String dName) {
- mDName = dName;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getDName() {
- return mDName;
- }
-
- String getCertSha1Fingerprint() {
- return FingerprintUtils.getFingerprint(mCertificate, "SHA1");
- }
-
- String getCertMd5Fingerprint() {
- return FingerprintUtils.getFingerprint(mCertificate, "MD5");
- }
-
- void setSigningInfo(PrivateKey privateKey, X509Certificate certificate) {
- mPrivateKey = privateKey;
- mCertificate = certificate;
- }
-
- void setDestination(File destinationFile) {
- mDestinationFile = destinationFile;
- }
-
- void resetDestination() {
- mDestinationFile = null;
- }
-
- void updatePageOnChange(int changeMask) {
- for (ExportWizardPage page : mPages) {
- page.projectDataChanged(changeMask);
- }
- }
-
- private void displayError(String... messages) {
- String message = null;
- if (messages.length == 1) {
- message = messages[0];
- } else {
- StringBuilder sb = new StringBuilder(messages[0]);
- for (int i = 1; i < messages.length; i++) {
- sb.append('\n');
- sb.append(messages[i]);
- }
-
- message = sb.toString();
- }
-
- AdtPlugin.displayError("Export Wizard", message);
- }
-
- private void displayError(Throwable t) {
- String message = getExceptionMessage(t);
- displayError(message);
-
- AdtPlugin.log(t, "Export Wizard Error");
- }
-
- /**
- * Executes zipalign
- * @param zipAlignPath location of the zipalign too
- * @param source file to zipalign
- * @param destination where to write the resulting file
- * @return null if success, the error otherwise
- * @throws IOException
- */
- private String zipAlign(String zipAlignPath, File source, File destination) throws IOException {
- // command line: zipaling -f 4 tmp destination
- String[] command = new String[5];
- command[0] = zipAlignPath;
- command[1] = "-f"; //$NON-NLS-1$
- command[2] = "4"; //$NON-NLS-1$
- command[3] = source.getAbsolutePath();
- command[4] = destination.getAbsolutePath();
-
- Process process = Runtime.getRuntime().exec(command);
- final ArrayList<String> output = new ArrayList<String>();
- try {
- final IProject project = getProject();
-
- int status = GrabProcessOutput.grabProcessOutput(
- process,
- Wait.WAIT_FOR_READERS,
- new IProcessOutput() {
- @Override
- public void out(@Nullable String line) {
- if (line != null) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE,
- project, line);
- }
- }
-
- @Override
- public void err(@Nullable String line) {
- if (line != null) {
- output.add(line);
- }
- }
- });
-
- if (status != 0) {
- // build a single message from the array list
- StringBuilder sb = new StringBuilder("Error while running zipalign:");
- for (String msg : output) {
- sb.append('\n');
- sb.append(msg);
- }
-
- return sb.toString();
- }
- } catch (InterruptedException e) {
- // ?
- }
- return null;
- }
-
- /**
- * Returns the {@link Throwable#getMessage()}. If the {@link Throwable#getMessage()} returns
- * <code>null</code>, the method is called again on the cause of the Throwable object.
- * <p/>If no Throwable in the chain has a valid message, the canonical name of the first
- * exception is returned.
- */
- static String getExceptionMessage(Throwable t) {
- String message = t.getMessage();
- if (message == null) {
- // no error info? get the stack call to display it
- // At least that'll give us a better bug report.
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- t.printStackTrace(new PrintStream(baos));
- message = baos.toString();
- }
-
- return message;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
deleted file mode 100644
index c17f43e38..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-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.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.widgets.FormText;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Calendar;
-
-/**
- * Final page of the wizard that checks the key and ask for the ouput location.
- */
-final class KeyCheckPage extends ExportWizardPage {
-
- private static final int REQUIRED_YEARS = 25;
-
- private static final String VALIDITY_WARNING =
- "<p>Make sure the certificate is valid for the planned lifetime of the product.</p>"
- + "<p>If the certificate expires, you will be forced to sign your application with "
- + "a different one.</p>"
- + "<p>Applications cannot be upgraded if their certificate changes from "
- + "one version to another, forcing a full uninstall/install, which will make "
- + "the user lose his/her data.</p>"
- + "<p>Google Play(Android Market) currently requires certificates to be valid "
- + "until 2033.</p>";
-
- private final ExportWizard mWizard;
- private PrivateKey mPrivateKey;
- private X509Certificate mCertificate;
- private Text mDestination;
- private boolean mFatalSigningError;
- private FormText mDetailText;
- private ScrolledComposite mScrolledComposite;
-
- private String mKeyDetails;
- private String mDestinationDetails;
-
- protected KeyCheckPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Destination and key/certificate checks");
- setDescription(""); // TODO
- }
-
- @Override
- public void createControl(Composite parent) {
- setErrorMessage(null);
- setMessage(null);
-
- // build the ui.
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout gl = new GridLayout(3, false);
- gl.verticalSpacing *= 3;
- composite.setLayout(gl);
-
- GridData gd;
-
- new Label(composite, SWT.NONE).setText("Destination APK file:");
- mDestination = new Text(composite, SWT.BORDER);
- mDestination.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mDestination.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onDestinationChange(false /*forceDetailUpdate*/);
- }
- });
- final Button browseButton = new Button(composite, SWT.PUSH);
- browseButton.setText("Browse...");
- browseButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- FileDialog fileDialog = new FileDialog(browseButton.getShell(), SWT.SAVE);
-
- fileDialog.setText("Destination file name");
- // get a default apk name based on the project
- String filename = ProjectHelper.getApkFilename(mWizard.getProject(),
- null /*config*/);
- fileDialog.setFileName(filename);
-
- String saveLocation = fileDialog.open();
- if (saveLocation != null) {
- mDestination.setText(saveLocation);
- }
- }
- });
-
- mScrolledComposite = new ScrolledComposite(composite, SWT.V_SCROLL);
- mScrolledComposite.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
- gd.horizontalSpan = 3;
- mScrolledComposite.setExpandHorizontal(true);
- mScrolledComposite.setExpandVertical(true);
-
- mDetailText = new FormText(mScrolledComposite, SWT.NONE);
- mScrolledComposite.setContent(mDetailText);
-
- mScrolledComposite.addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(ControlEvent e) {
- updateScrolling();
- }
- });
-
- setControl(composite);
- }
-
- @Override
- void onShow() {
- // fill the texts with information loaded from the project.
- if ((mProjectDataChanged & DATA_PROJECT) != 0) {
- // reset the destination from the content of the project
- IProject project = mWizard.getProject();
-
- String destination = ProjectHelper.loadStringProperty(project,
- ExportWizard.PROPERTY_DESTINATION);
- if (destination != null) {
- mDestination.setText(destination);
- }
- }
-
- // if anything change we basically reload the data.
- if (mProjectDataChanged != 0) {
- mFatalSigningError = false;
-
- // reset the wizard with no key/cert to make it not finishable, unless a valid
- // key/cert is found.
- mWizard.setSigningInfo(null, null);
- mPrivateKey = null;
- mCertificate = null;
- mKeyDetails = null;
-
- if (mWizard.getKeystoreCreationMode() || mWizard.getKeyCreationMode()) {
- int validity = mWizard.getValidity();
- StringBuilder sb = new StringBuilder(
- String.format("<p>Certificate expires in %d years.</p>",
- validity));
-
- if (validity < REQUIRED_YEARS) {
- sb.append(VALIDITY_WARNING);
- }
-
- mKeyDetails = sb.toString();
- } else {
- try {
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream fis = new FileInputStream(mWizard.getKeystore());
- keyStore.load(fis, mWizard.getKeystorePassword().toCharArray());
- fis.close();
- PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
- mWizard.getKeyAlias(),
- new KeyStore.PasswordProtection(
- mWizard.getKeyPassword().toCharArray()));
-
- if (entry != null) {
- mPrivateKey = entry.getPrivateKey();
- mCertificate = (X509Certificate)entry.getCertificate();
- } else {
- setErrorMessage("Unable to find key.");
-
- setPageComplete(false);
- }
- } catch (FileNotFoundException e) {
- // this was checked at the first previous step and will not happen here, unless
- // the file was removed during the export wizard execution.
- onException(e);
- } catch (KeyStoreException e) {
- onException(e);
- } catch (NoSuchAlgorithmException e) {
- onException(e);
- } catch (UnrecoverableEntryException e) {
- onException(e);
- } catch (CertificateException e) {
- onException(e);
- } catch (IOException e) {
- onException(e);
- }
-
- if (mPrivateKey != null && mCertificate != null) {
- Calendar expirationCalendar = Calendar.getInstance();
- expirationCalendar.setTime(mCertificate.getNotAfter());
- Calendar today = Calendar.getInstance();
-
- if (expirationCalendar.before(today)) {
- mKeyDetails = String.format(
- "<p>Certificate expired on %s</p>",
- mCertificate.getNotAfter().toString());
-
- // fatal error = nothing can make the page complete.
- mFatalSigningError = true;
-
- setErrorMessage("Certificate is expired.");
- setPageComplete(false);
- } else {
- // valid, key/cert: put it in the wizard so that it can be finished
- mWizard.setSigningInfo(mPrivateKey, mCertificate);
-
- StringBuilder sb = new StringBuilder(String.format(
- "<p>Certificate expires on %s.</p>",
- mCertificate.getNotAfter().toString()));
-
- int expirationYear = expirationCalendar.get(Calendar.YEAR);
- int thisYear = today.get(Calendar.YEAR);
-
- if (thisYear + REQUIRED_YEARS < expirationYear) {
- // do nothing
- } else {
- if (expirationYear == thisYear) {
- sb.append("<p>The certificate expires this year.</p>");
- } else {
- int count = expirationYear-thisYear;
- sb.append(String.format(
- "<p>The Certificate expires in %1$s %2$s.</p>",
- count, count == 1 ? "year" : "years"));
- }
- sb.append(VALIDITY_WARNING);
- }
-
- // show certificate fingerprints
- String sha1 = mWizard.getCertSha1Fingerprint();
- String md5 = mWizard.getCertMd5Fingerprint();
-
- sb.append("<p></p>" /*blank line*/);
- sb.append("<p>Certificate fingerprints:</p>");
- sb.append(String.format("<li>MD5 : %s</li>", md5));
- sb.append(String.format("<li>SHA1: %s</li>", sha1));
- sb.append("<p></p>" /*blank line*/);
-
- mKeyDetails = sb.toString();
- }
- } else {
- // fatal error = nothing can make the page complete.
- mFatalSigningError = true;
- }
- }
- }
-
- onDestinationChange(true /*forceDetailUpdate*/);
- }
-
- /**
- * Callback for destination field edition
- * @param forceDetailUpdate if true, the detail {@link FormText} is updated even if a fatal
- * error has happened in the signing.
- */
- private void onDestinationChange(boolean forceDetailUpdate) {
- if (mFatalSigningError == false) {
- // reset messages for now.
- setErrorMessage(null);
- setMessage(null);
-
- String path = mDestination.getText().trim();
-
- if (path.length() == 0) {
- setErrorMessage("Enter destination for the APK file.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- File file = new File(path);
- if (file.isDirectory()) {
- setErrorMessage("Destination is a directory.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- File parentFolder = file.getParentFile();
- if (parentFolder == null || parentFolder.isDirectory() == false) {
- setErrorMessage("Not a valid directory.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- if (file.isFile()) {
- mDestinationDetails = "<li>WARNING: destination file already exists</li>";
- setMessage("Destination file already exists.", WARNING);
- }
-
- // no error, set the destination in the wizard.
- mWizard.setDestination(file);
- setPageComplete(true);
-
- updateDetailText();
- } else if (forceDetailUpdate) {
- updateDetailText();
- }
- }
-
- /**
- * Updates the scrollbar to match the content of the {@link FormText} or the new size
- * of the {@link ScrolledComposite}.
- */
- private void updateScrolling() {
- if (mDetailText != null) {
- Rectangle r = mScrolledComposite.getClientArea();
- mScrolledComposite.setMinSize(mDetailText.computeSize(r.width, SWT.DEFAULT));
- mScrolledComposite.layout();
- }
- }
-
- private void updateDetailText() {
- StringBuilder sb = new StringBuilder("<form>");
- if (mKeyDetails != null) {
- sb.append(mKeyDetails);
- }
-
- if (mDestinationDetails != null && mFatalSigningError == false) {
- sb.append(mDestinationDetails);
- }
-
- sb.append("</form>");
-
- mDetailText.setText(sb.toString(), true /* parseTags */,
- true /* expandURLs */);
-
- mDetailText.getParent().layout();
-
- updateScrolling();
- }
-
- @Override
- protected void onException(Throwable t) {
- super.onException(t);
-
- mKeyDetails = String.format("ERROR: %1$s", ExportWizard.getExceptionMessage(t));
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java
deleted file mode 100644
index aea94ad8d..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.util.List;
-
-/**
- * Key creation page.
- */
-final class KeyCreationPage extends ExportWizardPage {
-
- private final ExportWizard mWizard;
- private Text mAlias;
- private Text mKeyPassword;
- private Text mKeyPassword2;
- private Text mCnField;
- private boolean mDisableOnChange = false;
- private Text mOuField;
- private Text mOField;
- private Text mLField;
- private Text mStField;
- private Text mCField;
- private String mDName;
- private int mValidity = 0;
- private List<String> mExistingAliases;
-
-
- protected KeyCreationPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Key Creation");
- setDescription(""); // TODO?
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout gl = new GridLayout(2, false);
- composite.setLayout(gl);
-
- GridData gd;
-
- new Label(composite, SWT.NONE).setText("Alias:");
- mAlias = new Text(composite, SWT.BORDER);
- mAlias.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("Password:");
- mKeyPassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
- mKeyPassword.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mKeyPassword.addVerifyListener(sPasswordVerifier);
-
- new Label(composite, SWT.NONE).setText("Confirm:");
- mKeyPassword2 = new Text(composite, SWT.BORDER | SWT.PASSWORD);
- mKeyPassword2.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mKeyPassword2.addVerifyListener(sPasswordVerifier);
-
- new Label(composite, SWT.NONE).setText("Validity (years):");
- final Text validityText = new Text(composite, SWT.BORDER);
- validityText.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- validityText.addVerifyListener(new VerifyListener() {
- @Override
- public void verifyText(VerifyEvent e) {
- // check for digit only.
- for (int i = 0 ; i < e.text.length(); i++) {
- char letter = e.text.charAt(i);
- if (letter < '0' || letter > '9') {
- e.doit = false;
- return;
- }
- }
- }
- });
-
- new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(
- gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 2;
-
- new Label(composite, SWT.NONE).setText("First and Last Name:");
- mCnField = new Text(composite, SWT.BORDER);
- mCnField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("Organizational Unit:");
- mOuField = new Text(composite, SWT.BORDER);
- mOuField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("Organization:");
- mOField = new Text(composite, SWT.BORDER);
- mOField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("City or Locality:");
- mLField = new Text(composite, SWT.BORDER);
- mLField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("State or Province:");
- mStField = new Text(composite, SWT.BORDER);
- mStField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- new Label(composite, SWT.NONE).setText("Country Code (XX):");
- mCField = new Text(composite, SWT.BORDER);
- mCField.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
-
- // Show description the first time
- setErrorMessage(null);
- setMessage(null);
- setControl(composite);
-
- mAlias.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mWizard.setKeyAlias(mAlias.getText().trim());
- onChange();
- }
- });
- mKeyPassword.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mWizard.setKeyPassword(mKeyPassword.getText());
- onChange();
- }
- });
- mKeyPassword2.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onChange();
- }
- });
-
- validityText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- try {
- mValidity = Integer.parseInt(validityText.getText());
- } catch (NumberFormatException e2) {
- // this should only happen if the text field is empty due to the verifyListener.
- mValidity = 0;
- }
- mWizard.setValidity(mValidity);
- onChange();
- }
- });
-
- ModifyListener dNameListener = new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onDNameChange();
- }
- };
-
- mCnField.addModifyListener(dNameListener);
- mOuField.addModifyListener(dNameListener);
- mOField.addModifyListener(dNameListener);
- mLField.addModifyListener(dNameListener);
- mStField.addModifyListener(dNameListener);
- mCField.addModifyListener(dNameListener);
- }
-
- @Override
- void onShow() {
- // fill the texts with information loaded from the project.
- if ((mProjectDataChanged & (DATA_PROJECT | DATA_KEYSTORE)) != 0) {
- // reset the keystore/alias from the content of the project
- IProject project = mWizard.getProject();
-
- // disable onChange for now. we'll call it once at the end.
- mDisableOnChange = true;
-
- String alias = ProjectHelper.loadStringProperty(project, ExportWizard.PROPERTY_ALIAS);
- if (alias != null) {
- mAlias.setText(alias);
- }
-
- // get the existing list of keys if applicable
- if (mWizard.getKeyCreationMode()) {
- mExistingAliases = mWizard.getExistingAliases();
- } else {
- mExistingAliases = null;
- }
-
- // reset the passwords
- mKeyPassword.setText(""); //$NON-NLS-1$
- mKeyPassword2.setText(""); //$NON-NLS-1$
-
- // enable onChange, and call it to display errors and enable/disable pageCompleted.
- mDisableOnChange = false;
- onChange();
- }
- }
-
- @Override
- public IWizardPage getPreviousPage() {
- if (mWizard.getKeyCreationMode()) { // this means we create a key from an existing store
- return mWizard.getKeySelectionPage();
- }
-
- return mWizard.getKeystoreSelectionPage();
- }
-
- @Override
- public IWizardPage getNextPage() {
- return mWizard.getKeyCheckPage();
- }
-
- /**
- * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
- */
- private void onChange() {
- if (mDisableOnChange) {
- return;
- }
-
- setErrorMessage(null);
- setMessage(null);
-
- if (mAlias.getText().trim().length() == 0) {
- setErrorMessage("Enter key alias.");
- setPageComplete(false);
- return;
- } else if (mExistingAliases != null) {
- // we cannot use indexOf, because we need to do a case-insensitive check
- String keyAlias = mAlias.getText().trim();
- for (String alias : mExistingAliases) {
- if (alias.equalsIgnoreCase(keyAlias)) {
- setErrorMessage("Key alias already exists in keystore.");
- setPageComplete(false);
- return;
- }
- }
- }
-
- String value = mKeyPassword.getText();
- if (value.length() == 0) {
- setErrorMessage("Enter key password.");
- setPageComplete(false);
- return;
- } else if (value.length() < 6) {
- setErrorMessage("Key password is too short - must be at least 6 characters.");
- setPageComplete(false);
- return;
- }
-
- if (value.equals(mKeyPassword2.getText()) == false) {
- setErrorMessage("Key passwords don't match.");
- setPageComplete(false);
- return;
- }
-
- if (mValidity == 0) {
- setErrorMessage("Key certificate validity is required.");
- setPageComplete(false);
- return;
- } else if (mValidity < 25) {
- setMessage("A 25 year certificate validity is recommended.", WARNING);
- } else if (mValidity > 1000) {
- setErrorMessage("Key certificate validity must be between 1 and 1000 years.");
- setPageComplete(false);
- return;
- }
-
- if (mDName == null || mDName.length() == 0) {
- setErrorMessage("At least one Certificate issuer field is required to be non-empty.");
- setPageComplete(false);
- return;
- }
-
- setPageComplete(true);
- }
-
- /**
- * Handles changes in the DName fields.
- */
- private void onDNameChange() {
- StringBuilder sb = new StringBuilder();
-
- buildDName("CN", mCnField, sb);
- buildDName("OU", mOuField, sb);
- buildDName("O", mOField, sb);
- buildDName("L", mLField, sb);
- buildDName("ST", mStField, sb);
- buildDName("C", mCField, sb);
-
- mDName = sb.toString();
- mWizard.setDName(mDName);
-
- onChange();
- }
-
- /**
- * Builds the distinguished name string with the provided {@link StringBuilder}.
- * @param prefix the prefix of the entry.
- * @param textField The {@link Text} field containing the entry value.
- * @param sb the string builder containing the dname.
- */
- private void buildDName(String prefix, Text textField, StringBuilder sb) {
- if (textField != null) {
- String value = textField.getText().trim();
- if (value.length() > 0) {
- if (sb.length() > 0) {
- sb.append(",");
- }
-
- sb.append(prefix);
- sb.append('=');
- sb.append(value);
- }
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java
deleted file mode 100644
index 604a208e6..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-
-/**
- * Key Selection Page. This is used when an existing keystore is used.
- */
-final class KeySelectionPage extends ExportWizardPage {
-
- private final ExportWizard mWizard;
- private Label mKeyAliasesLabel;
- private Combo mKeyAliases;
- private Label mKeyPasswordLabel;
- private Text mKeyPassword;
- private boolean mDisableOnChange = false;
- private Button mUseExistingKey;
- private Button mCreateKey;
-
- protected KeySelectionPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Key alias selection");
- setDescription(""); // TODO
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout gl = new GridLayout(3, false);
- composite.setLayout(gl);
-
- GridData gd;
-
- mUseExistingKey = new Button(composite, SWT.RADIO);
- mUseExistingKey.setText("Use existing key");
- mUseExistingKey.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 3;
- mUseExistingKey.setSelection(true);
-
- new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
- gd.heightHint = 0;
- gd.widthHint = 50;
- mKeyAliasesLabel = new Label(composite, SWT.NONE);
- mKeyAliasesLabel.setText("Alias:");
- mKeyAliases = new Combo(composite, SWT.READ_ONLY);
- mKeyAliases.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
- gd.heightHint = 0;
- gd.widthHint = 50;
- mKeyPasswordLabel = new Label(composite, SWT.NONE);
- mKeyPasswordLabel.setText("Password:");
- mKeyPassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
- mKeyPassword.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mCreateKey = new Button(composite, SWT.RADIO);
- mCreateKey.setText("Create new key");
- mCreateKey.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 3;
-
- // Show description the first time
- setErrorMessage(null);
- setMessage(null);
- setControl(composite);
-
- mUseExistingKey.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- mWizard.setKeyCreationMode(!mUseExistingKey.getSelection());
- enableWidgets();
- onChange();
- }
- });
-
- mKeyAliases.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- mWizard.setKeyAlias(mKeyAliases.getItem(mKeyAliases.getSelectionIndex()));
- onChange();
- }
- });
-
- mKeyPassword.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mWizard.setKeyPassword(mKeyPassword.getText());
- onChange();
- }
- });
- }
-
- @Override
- void onShow() {
- // fill the texts with information loaded from the project.
- if ((mProjectDataChanged & (DATA_PROJECT | DATA_KEYSTORE)) != 0) {
- // disable onChange for now. we'll call it once at the end.
- mDisableOnChange = true;
-
- // reset the alias from the content of the project
- try {
- // reset to using a key
- mWizard.setKeyCreationMode(false);
- mUseExistingKey.setSelection(true);
- mCreateKey.setSelection(false);
- enableWidgets();
-
- // remove the content of the alias combo always and first, in case the
- // keystore password is wrong
- mKeyAliases.removeAll();
-
- // get the alias list (also used as a keystore password test)
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream fis = new FileInputStream(mWizard.getKeystore());
- keyStore.load(fis, mWizard.getKeystorePassword().toCharArray());
- fis.close();
-
- Enumeration<String> aliases = keyStore.aliases();
-
- // get the alias from the project previous export, and look for a match as
- // we add the aliases to the combo.
- IProject project = mWizard.getProject();
-
- String keyAlias = ProjectHelper.loadStringProperty(project,
- ExportWizard.PROPERTY_ALIAS);
-
- ArrayList<String> aliasList = new ArrayList<String>();
-
- int selection = -1;
- int count = 0;
- while (aliases.hasMoreElements()) {
- String alias = aliases.nextElement();
- mKeyAliases.add(alias);
- aliasList.add(alias);
- if (selection == -1 && alias.equalsIgnoreCase(keyAlias)) {
- selection = count;
- }
- count++;
- }
-
- mWizard.setExistingAliases(aliasList);
-
- if (selection != -1) {
- mKeyAliases.select(selection);
-
- // since a match was found and is selected, we need to give it to
- // the wizard as well
- mWizard.setKeyAlias(keyAlias);
- } else {
- mKeyAliases.clearSelection();
- }
-
- // reset the password
- mKeyPassword.setText(""); //$NON-NLS-1$
-
- // enable onChange, and call it to display errors and enable/disable pageCompleted.
- mDisableOnChange = false;
- onChange();
- } catch (KeyStoreException e) {
- onException(e);
- } catch (FileNotFoundException e) {
- onException(e);
- } catch (NoSuchAlgorithmException e) {
- onException(e);
- } catch (CertificateException e) {
- onException(e);
- } catch (IOException e) {
- onException(e);
- } finally {
- // in case we exit with an exception, we need to reset this
- mDisableOnChange = false;
- }
- }
- }
-
- @Override
- public IWizardPage getPreviousPage() {
- return mWizard.getKeystoreSelectionPage();
- }
-
- @Override
- public IWizardPage getNextPage() {
- if (mWizard.getKeyCreationMode()) {
- return mWizard.getKeyCreationPage();
- }
-
- return mWizard.getKeyCheckPage();
- }
-
- /**
- * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
- */
- private void onChange() {
- if (mDisableOnChange) {
- return;
- }
-
- setErrorMessage(null);
- setMessage(null);
-
- if (mWizard.getKeyCreationMode() == false) {
- if (mKeyAliases.getSelectionIndex() == -1) {
- setErrorMessage("Select a key alias.");
- setPageComplete(false);
- return;
- }
-
- if (mKeyPassword.getText().trim().length() == 0) {
- setErrorMessage("Enter key password.");
- setPageComplete(false);
- return;
- }
- }
-
- setPageComplete(true);
- }
-
- private void enableWidgets() {
- boolean useKey = !mWizard.getKeyCreationMode();
- mKeyAliasesLabel.setEnabled(useKey);
- mKeyAliases.setEnabled(useKey);
- mKeyPassword.setEnabled(useKey);
- mKeyPasswordLabel.setEnabled(useKey);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java
deleted file mode 100644
index eabee15a2..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/**
- * Keystore selection page. This page allows to choose to create a new keystore or use an
- * existing one.
- */
-final class KeystoreSelectionPage extends ExportWizardPage {
-
- private final ExportWizard mWizard;
- private Button mUseExistingKeystore;
- private Button mCreateKeystore;
- private Text mKeystore;
- private Text mKeystorePassword;
- private Label mConfirmLabel;
- private Text mKeystorePassword2;
- private boolean mDisableOnChange = false;
-
- protected KeystoreSelectionPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Keystore selection");
- setDescription(""); //TODO
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout gl = new GridLayout(3, false);
- composite.setLayout(gl);
-
- GridData gd;
-
- mUseExistingKeystore = new Button(composite, SWT.RADIO);
- mUseExistingKeystore.setText("Use existing keystore");
- mUseExistingKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 3;
- mUseExistingKeystore.setSelection(true);
-
- mCreateKeystore = new Button(composite, SWT.RADIO);
- mCreateKeystore.setText("Create new keystore");
- mCreateKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 3;
-
- new Label(composite, SWT.NONE).setText("Location:");
- mKeystore = new Text(composite, SWT.BORDER);
- mKeystore.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- final Button browseButton = new Button(composite, SWT.PUSH);
- browseButton.setText("Browse...");
- browseButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- FileDialog fileDialog;
- if (mUseExistingKeystore.getSelection()) {
- fileDialog = new FileDialog(browseButton.getShell(),SWT.OPEN);
- fileDialog.setText("Load Keystore");
- } else {
- fileDialog = new FileDialog(browseButton.getShell(),SWT.SAVE);
- fileDialog.setText("Select Keystore Name");
- }
-
- String fileName = fileDialog.open();
- if (fileName != null) {
- mKeystore.setText(fileName);
- }
- }
- });
-
- new Label(composite, SWT.NONE).setText("Password:");
- mKeystorePassword = new Text(composite, SWT.BORDER | SWT.PASSWORD);
- mKeystorePassword.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mKeystorePassword.addVerifyListener(sPasswordVerifier);
- new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
- gd.heightHint = gd.widthHint = 0;
-
- mConfirmLabel = new Label(composite, SWT.NONE);
- mConfirmLabel.setText("Confirm:");
- mKeystorePassword2 = new Text(composite, SWT.BORDER | SWT.PASSWORD);
- mKeystorePassword2.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mKeystorePassword2.addVerifyListener(sPasswordVerifier);
- new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData());
- gd.heightHint = gd.widthHint = 0;
- mKeystorePassword2.setEnabled(false);
-
- // Show description the first time
- setErrorMessage(null);
- setMessage(null);
- setControl(composite);
-
- mUseExistingKeystore.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- boolean createStore = !mUseExistingKeystore.getSelection();
- mKeystorePassword2.setEnabled(createStore);
- mConfirmLabel.setEnabled(createStore);
- mWizard.setKeystoreCreationMode(createStore);
- onChange();
- }
- });
-
- mKeystore.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mWizard.setKeystore(mKeystore.getText().trim());
- onChange();
- }
- });
-
- mKeystorePassword.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mWizard.setKeystorePassword(mKeystorePassword.getText());
- onChange();
- }
- });
-
- mKeystorePassword2.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onChange();
- }
- });
- }
-
- @Override
- public IWizardPage getNextPage() {
- if (mUseExistingKeystore.getSelection()) {
- return mWizard.getKeySelectionPage();
- }
-
- return mWizard.getKeyCreationPage();
- }
-
- @Override
- void onShow() {
- // fill the texts with information loaded from the project.
- if ((mProjectDataChanged & DATA_PROJECT) != 0) {
- // reset the keystore/alias from the content of the project
- IProject project = mWizard.getProject();
-
- // disable onChange for now. we'll call it once at the end.
- mDisableOnChange = true;
-
- String keystore = ProjectHelper.loadStringProperty(project,
- ExportWizard.PROPERTY_KEYSTORE);
- if (keystore != null) {
- mKeystore.setText(keystore);
- }
-
- // reset the passwords
- mKeystorePassword.setText(""); //$NON-NLS-1$
- mKeystorePassword2.setText(""); //$NON-NLS-1$
-
- // enable onChange, and call it to display errors and enable/disable pageCompleted.
- mDisableOnChange = false;
- onChange();
- }
- }
-
- /**
- * Handles changes and update the error message and calls {@link #setPageComplete(boolean)}.
- */
- private void onChange() {
- if (mDisableOnChange) {
- return;
- }
-
- setErrorMessage(null);
- setMessage(null);
-
- boolean createStore = !mUseExistingKeystore.getSelection();
-
- // checks the keystore path is non null.
- String keystore = mKeystore.getText().trim();
- if (keystore.length() == 0) {
- setErrorMessage("Enter path to keystore.");
- setPageComplete(false);
- return;
- } else {
- File f = new File(keystore);
- if (f.exists() == false) {
- if (createStore == false) {
- setErrorMessage("Keystore does not exist.");
- setPageComplete(false);
- return;
- }
- } else if (f.isDirectory()) {
- setErrorMessage("Keystore path is a directory.");
- setPageComplete(false);
- return;
- } else if (f.isFile()) {
- if (createStore) {
- setErrorMessage("File already exists.");
- setPageComplete(false);
- return;
- }
- }
- }
-
- String value = mKeystorePassword.getText();
- if (value.length() == 0) {
- setErrorMessage("Enter keystore password.");
- setPageComplete(false);
- return;
- } else if (createStore && value.length() < 6) {
- setErrorMessage("Keystore password is too short - must be at least 6 characters.");
- setPageComplete(false);
- return;
- }
-
- if (createStore) {
- if (mKeystorePassword2.getText().length() == 0) {
- setErrorMessage("Confirm keystore password.");
- setPageComplete(false);
- return;
- }
-
- if (mKeystorePassword.getText().equals(mKeystorePassword2.getText()) == false) {
- setErrorMessage("Keystore passwords do not match.");
- setPageComplete(false);
- return;
- }
- }
-
- setPageComplete(true);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java
deleted file mode 100644
index b8a7043da..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2008 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.export;
-
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-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.NonLibraryProjectOnlyFilter;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Text;
-
-/**
- * First Export Wizard Page. Display warning/errors.
- */
-final class ProjectCheckPage extends ExportWizardPage {
- private final static String IMG_ERROR = "error.png"; //$NON-NLS-1$
- private final static String IMG_WARNING = "warning.png"; //$NON-NLS-1$
-
- private final ExportWizard mWizard;
- private Image mError;
- private Image mWarning;
- private boolean mHasMessage = false;
- private Composite mTopComposite;
- private Composite mErrorComposite;
- private Text mProjectText;
- private ProjectChooserHelper mProjectChooserHelper;
- private boolean mFirstOnShow = true;
-
- protected ProjectCheckPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Project Checks");
- setDescription("Performs a set of checks to make sure the application can be exported.");
- }
-
- @Override
- public void createControl(Composite parent) {
- mProjectChooserHelper = new ProjectChooserHelper(parent.getShell(),
- new NonLibraryProjectOnlyFilter());
-
- GridLayout gl = null;
- GridData gd = null;
-
- mTopComposite = new Composite(parent, SWT.NONE);
- mTopComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
- mTopComposite.setLayout(new GridLayout(1, false));
-
- // composite for the project selection.
- Composite projectComposite = new Composite(mTopComposite, SWT.NONE);
- projectComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- projectComposite.setLayout(gl = new GridLayout(3, false));
- gl.marginHeight = gl.marginWidth = 0;
-
- Label label = new Label(projectComposite, SWT.NONE);
- label.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- gd.horizontalSpan = 3;
- label.setText("Select the project to export:");
-
- new Label(projectComposite, SWT.NONE).setText("Project:");
- mProjectText = new Text(projectComposite, SWT.BORDER);
- mProjectText.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mProjectText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- handleProjectNameChange();
- }
- });
-
- Button browseButton = new Button(projectComposite, SWT.PUSH);
- browseButton.setText("Browse...");
- browseButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- IJavaProject javaProject = mProjectChooserHelper.chooseJavaProject(
- mProjectText.getText().trim(),
- "Please select a project to export");
-
- if (javaProject != null) {
- IProject project = javaProject.getProject();
-
- // set the new name in the text field. The modify listener will take
- // care of updating the status and the ExportWizard object.
- mProjectText.setText(project.getName());
- }
- }
- });
-
- setControl(mTopComposite);
- }
-
- @Override
- void onShow() {
- if (mFirstOnShow) {
- // get the project and init the ui
- IProject project = mWizard.getProject();
- if (project != null) {
- mProjectText.setText(project.getName());
- }
-
- mFirstOnShow = false;
- }
- }
-
- private void buildErrorUi(IProject project) {
- // Show description the first time
- setErrorMessage(null);
- setMessage(null);
- setPageComplete(true);
- mHasMessage = false;
-
- // composite parent for the warning/error
- GridLayout gl = null;
- mErrorComposite = new Composite(mTopComposite, SWT.NONE);
- mErrorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- gl = new GridLayout(2, false);
- gl.marginHeight = gl.marginWidth = 0;
- gl.verticalSpacing *= 3; // more spacing than normal.
- mErrorComposite.setLayout(gl);
-
- if (project == null) {
- setErrorMessage("Select project to export.");
- mHasMessage = true;
- } else {
- try {
- if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
- addError(mErrorComposite, "Project is not an Android project.");
- } else {
- // check for errors
- if (ProjectHelper.hasError(project, true)) {
- addError(mErrorComposite, "Project has compilation error(s)");
- }
-
- // check the project output
- IFolder outputIFolder = BaseProjectHelper.getJavaOutputFolder(project);
- if (outputIFolder == null) {
- addError(mErrorComposite,
- "Unable to get the output folder of the project!");
- }
-
- // project is an android project, we check the debuggable attribute.
- ManifestData manifestData = AndroidManifestHelper.parseForData(project);
- Boolean debuggable = null;
- if (manifestData != null) {
- debuggable = manifestData.getDebuggable();
- }
-
- if (debuggable != null && debuggable == Boolean.TRUE) {
- addWarning(mErrorComposite,
- "The manifest 'debuggable' attribute is set to true.\n" +
- "You should set it to false for applications that you release to the public.\n\n" +
- "Applications with debuggable=true are compiled in debug mode always.");
- }
-
- // check for mapview stuff
- }
- } catch (CoreException e) {
- // unable to access nature
- addError(mErrorComposite, "Unable to get project nature");
- }
- }
-
- if (mHasMessage == false) {
- Label label = new Label(mErrorComposite, SWT.NONE);
- GridData gd = new GridData(GridData.FILL_HORIZONTAL);
- gd.horizontalSpan = 2;
- label.setLayoutData(gd);
- label.setText("No errors found. Click Next.");
- }
-
- mTopComposite.layout();
- }
-
- /**
- * Adds an error label to a {@link Composite} object.
- * @param parent the Composite parent.
- * @param message the error message.
- */
- private void addError(Composite parent, String message) {
- if (mError == null) {
- mError = IconFactory.getInstance().getIcon(IMG_ERROR);
- }
-
- new Label(parent, SWT.NONE).setImage(mError);
- Label label = new Label(parent, SWT.NONE);
- label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- label.setText(message);
-
- setErrorMessage("Application cannot be exported due to the error(s) below.");
- setPageComplete(false);
- mHasMessage = true;
- }
-
- /**
- * Adds a warning label to a {@link Composite} object.
- * @param parent the Composite parent.
- * @param message the warning message.
- */
- private void addWarning(Composite parent, String message) {
- if (mWarning == null) {
- mWarning = IconFactory.getInstance().getIcon(IMG_WARNING);
- }
-
- new Label(parent, SWT.NONE).setImage(mWarning);
- Label label = new Label(parent, SWT.NONE);
- label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- label.setText(message);
-
- mHasMessage = true;
- }
-
- /**
- * Checks the parameters for correctness, and update the error message and buttons.
- */
- private void handleProjectNameChange() {
- setPageComplete(false);
-
- if (mErrorComposite != null) {
- mErrorComposite.dispose();
- mErrorComposite = null;
- }
-
- // update the wizard with the new project
- mWizard.setProject(null);
-
- //test the project name first!
- String text = mProjectText.getText().trim();
- if (text.length() == 0) {
- setErrorMessage("Select project to export.");
- } else if (text.matches("[a-zA-Z0-9_ \\.-]+") == false) {
- setErrorMessage("Project name contains unsupported characters!");
- } else {
- IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null);
- IProject found = null;
- for (IJavaProject javaProject : projects) {
- if (javaProject.getProject().getName().equals(text)) {
- found = javaProject.getProject();
- break;
- }
-
- }
-
- if (found != null) {
- setErrorMessage(null);
-
- // update the wizard with the new project
- mWizard.setProject(found);
-
- // now rebuild the error ui.
- buildErrorUi(found);
- } else {
- setErrorMessage(String.format("There is no android project named '%1$s'",
- text));
- }
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java
deleted file mode 100644
index d3df0584f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/BuildFileCreator.java
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import static com.android.SdkConstants.GRADLE_LATEST_VERSION;
-import static com.android.SdkConstants.GRADLE_PLUGIN_LATEST_VERSION;
-import static com.android.SdkConstants.GRADLE_PLUGIN_NAME;
-import static com.android.tools.lint.checks.GradleDetector.APP_PLUGIN_ID;
-import static com.android.tools.lint.checks.GradleDetector.LIB_PLUGIN_ID;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.io.IFolderWrapper;
-import com.android.io.IAbstractFile;
-import com.android.sdklib.io.FileOp;
-import com.android.xml.AndroidManifest;
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.common.io.Closeables;
-import com.google.common.io.Files;
-
-import org.eclipse.core.resources.IFile;
-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.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * Creates build.gradle and settings.gradle files for a set of projects.
- * <p>
- * Based on {@link org.eclipse.ant.internal.ui.datatransfer.BuildFileCreator}
- */
-public class BuildFileCreator {
- static final String BUILD_FILE = "build.gradle"; //$NON-NLS-1$
- static final String SETTINGS_FILE = "settings.gradle"; //$NON-NLS-1$
- private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
- private static final String GRADLE_WRAPPER_LOCATION =
- "tools/templates/gradle/wrapper"; //$NON-NLS-1$
- static final String PLUGIN_CLASSPATH =
- "classpath '" + GRADLE_PLUGIN_NAME + GRADLE_PLUGIN_LATEST_VERSION + "'"; //$NON-NLS-1$
- static final String MAVEN_REPOSITORY = "jcenter()"; //$NON-NLS-1$
-
- private static final String[] GRADLE_WRAPPER_FILES = new String[] {
- "gradlew", //$NON-NLS-1$
- "gradlew.bat", //$NON-NLS-1$
- "gradle/wrapper/gradle-wrapper.jar", //$NON-NLS-1$
- "gradle/wrapper/gradle-wrapper.properties" //$NON-NLS-1$
- };
-
- private static final Comparator<IFile> FILE_COMPARATOR = new Comparator<IFile>() {
- @Override
- public int compare(IFile o1, IFile o2) {
- return o1.toString().compareTo(o2.toString());
- }
- };
-
- private final GradleModule mModule;
- private final StringBuilder mBuildFile = new StringBuilder();
-
- /**
- * Create buildfile for the projects.
- *
- * @param shell parent instance for dialogs
- * @return project names for which buildfiles were created
- * @throws InterruptedException thrown when user cancels task
- */
- public static void createBuildFiles(
- @NonNull ProjectSetupBuilder builder,
- @NonNull Shell shell,
- @NonNull IProgressMonitor pm) {
-
- File gradleLocation = new File(Sdk.getCurrent().getSdkOsLocation(), GRADLE_WRAPPER_LOCATION);
- SubMonitor localmonitor = null;
-
- try {
- // See if we have a Gradle wrapper in the SDK templates directory. If so, we can copy
- // it over.
- boolean hasGradleWrapper = true;
- for (File wrapperFile : getGradleWrapperFiles(gradleLocation)) {
- if (!wrapperFile.exists()) {
- hasGradleWrapper = false;
- }
- }
-
- Collection<GradleModule> modules = builder.getModules();
- boolean multiModules = modules.size() > 1;
-
- // determine files to create/change
- List<IFile> files = new ArrayList<IFile>();
-
- // add the build.gradle file for all modules.
- for (GradleModule module : modules) {
- // build.gradle file
- IFile file = module.getProject().getFile(BuildFileCreator.BUILD_FILE);
- files.add(file);
- }
-
- // get the commonRoot for all modules. If only one module, this returns the path
- // of the project.
- IPath commonRoot = builder.getCommonRoot();
-
- IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
- IPath workspaceLocation = workspaceRoot.getLocation();
-
- IPath relativePath = commonRoot.makeRelativeTo(workspaceLocation);
- // if makeRelativePath to returns the same path, then commonRoot is not in the
- // workspace.
- boolean rootInWorkspace = !relativePath.equals(commonRoot);
- // we only care if the root is a workspace project. if it's the workspace folder itself,
- // then the files won't be handled by the workspace.
- rootInWorkspace = rootInWorkspace && relativePath.segmentCount() > 0;
-
- File settingsFile = new File(commonRoot.toFile(), SETTINGS_FILE);
-
- // more than one modules -> generate settings.gradle
- if (multiModules && rootInWorkspace) {
-
- // Locate the settings.gradle file and add it to the changed files list
- IPath settingsGradle = Path.fromOSString(settingsFile.getAbsolutePath());
-
- // different path, means commonRoot is inside the workspace, which means we have
- // to add settings.gradle and wrapper files to the list of files to add.
- IFile iFile = workspaceRoot.getFile(settingsGradle);
- if (iFile != null) {
- files.add(iFile);
- }
- }
-
- // Gradle wrapper files
- if (hasGradleWrapper && rootInWorkspace) {
- // See if there already wrapper files there and only mark nonexistent ones for
- // creation.
- for (File wrapperFile : getGradleWrapperFiles(commonRoot.toFile())) {
- if (!wrapperFile.exists()) {
- IPath path = Path.fromOSString(wrapperFile.getAbsolutePath());
- IFile file = workspaceRoot.getFile(path);
- files.add(file);
- }
- }
- }
-
- ExportStatus status = new ExportStatus();
- builder.setStatus(status);
-
- // Trigger checkout of changed files
- Set<IFile> confirmedFiles = validateEdit(files, status, shell);
-
- if (status.hasError()) {
- return;
- }
-
- // Now iterate over all the modules and generate the build files.
- localmonitor = SubMonitor.convert(pm, ExportMessages.PageTitle,
- confirmedFiles.size());
- List<String> projectSettingsPath = Lists.newArrayList();
- for (GradleModule currentModule : modules) {
- IProject moduleProject = currentModule.getProject();
-
- IFile file = moduleProject.getFile(BuildFileCreator.BUILD_FILE);
- if (!confirmedFiles.contains(file)) {
- continue;
- }
-
- localmonitor.setTaskName(NLS.bind(ExportMessages.FileStatusMessage,
- moduleProject.getName()));
-
- ProjectState projectState = Sdk.getProjectState(moduleProject);
- BuildFileCreator instance = new BuildFileCreator(currentModule, shell);
- if (projectState != null) {
- // This is an Android project
- if (!multiModules) {
- instance.appendBuildScript();
- }
- instance.appendHeader(projectState.isLibrary());
- instance.appendDependencies();
- instance.startAndroidTask(projectState);
- //instance.appendDefaultConfig();
- instance.createAndroidSourceSets();
- instance.finishAndroidTask();
- } else {
- // This is a plain Java project
- instance.appendJavaHeader();
- instance.createJavaSourceSets();
- }
-
- try {
- // Write the build file
- String buildfile = instance.mBuildFile.toString();
- InputStream is =
- new ByteArrayInputStream(buildfile.getBytes("UTF-8")); //$NON-NLS-1$
- if (file.exists()) {
- file.setContents(is, true, true, null);
- } else {
- file.create(is, true, null);
- }
- } catch (Exception e) {
- status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE,
- file.getLocation().toFile());
- status.setErrorMessage(e.getMessage());
- return;
- }
-
- if (localmonitor.isCanceled()) {
- return;
- }
- localmonitor.worked(1);
-
- // get the project path to add it to the settings.gradle.
- projectSettingsPath.add(currentModule.getPath());
- }
-
- // write the settings file.
- if (multiModules) {
- try {
- writeGradleSettingsFile(settingsFile, projectSettingsPath);
- } catch (IOException e) {
- status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, settingsFile);
- status.setErrorMessage(e.getMessage());
- return;
- }
- File mainBuildFile = new File(commonRoot.toFile(), BUILD_FILE);
- try {
- writeRootBuildGradle(mainBuildFile);
- } catch (IOException e) {
- status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, mainBuildFile);
- status.setErrorMessage(e.getMessage());
- return;
- }
- }
-
- // finally write the wrapper
- // TODO check we can based on where it is
- if (hasGradleWrapper) {
- copyGradleWrapper(gradleLocation, commonRoot.toFile(), status);
- if (status.hasError()) {
- return;
- }
- }
-
- } finally {
- if (localmonitor != null && !localmonitor.isCanceled()) {
- localmonitor.done();
- }
- if (pm != null) {
- pm.done();
- }
- }
- }
-
- /**
- * @param GradleModule create buildfile for this project
- * @param shell parent instance for dialogs
- */
- private BuildFileCreator(GradleModule module, Shell shell) {
- mModule = module;
- }
-
- /**
- * Return the files that comprise the Gradle wrapper as a collection of {@link File} instances.
- * @param root
- * @return
- */
- private static List<File> getGradleWrapperFiles(File root) {
- List<File> files = new ArrayList<File>(GRADLE_WRAPPER_FILES.length);
- for (String file : GRADLE_WRAPPER_FILES) {
- files.add(new File(root, file));
- }
- return files;
- }
-
- /**
- * Copy the Gradle wrapper files from one directory to another.
- */
- private static void copyGradleWrapper(File from, File to, ExportStatus status) {
- for (String file : GRADLE_WRAPPER_FILES) {
- File dest = new File(to, file);
- try {
- File src = new File(from, file);
- dest.getParentFile().mkdirs();
- new FileOp().copyFile(src, dest);
-
- if (src.getName().equals(GRADLE_PROPERTIES)) {
- updateGradleDistributionUrl(GRADLE_LATEST_VERSION, dest);
- }
- dest.setExecutable(src.canExecute());
- status.addFileStatus(ExportStatus.FileStatus.OK, dest);
- } catch (IOException e) {
- status.addFileStatus(ExportStatus.FileStatus.IO_FAILURE, dest);
- return;
- }
- }
- }
-
- /**
- * Outputs boilerplate buildscript information common to all Gradle build files.
- */
- private void appendBuildScript() {
- appendBuildScript(mBuildFile);
- }
-
- /**
- * Outputs boilerplate header information common to all Gradle build files.
- */
- private static void appendBuildScript(StringBuilder builder) {
- builder.append("buildscript {\n"); //$NON-NLS-1$
- builder.append(" repositories {\n"); //$NON-NLS-1$
- builder.append(" " + MAVEN_REPOSITORY + "\n"); //$NON-NLS-1$
- builder.append(" }\n"); //$NON-NLS-1$
- builder.append(" dependencies {\n"); //$NON-NLS-1$
- builder.append(" " + PLUGIN_CLASSPATH + "\n"); //$NON-NLS-1$
- builder.append(" }\n"); //$NON-NLS-1$
- builder.append("}\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs boilerplate header information common to all Gradle build files.
- */
- private void appendHeader(boolean isLibrary) {
- if (isLibrary) {
- mBuildFile.append("apply plugin: '").append(LIB_PLUGIN_ID).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- mBuildFile.append("apply plugin: '").append(APP_PLUGIN_ID).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- mBuildFile.append("\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs a block which sets up library and project dependencies.
- */
- private void appendDependencies() {
- mBuildFile.append("dependencies {\n"); //$NON-NLS-1$
-
- // first the local jars.
- // TODO: Fix
- mBuildFile.append(" compile fileTree(dir: 'libs', include: '*.jar')\n"); //$NON-NLS-1$
-
- for (GradleModule dep : mModule.getDependencies()) {
- mBuildFile.append(" compile project('" + dep.getPath() + "')\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- mBuildFile.append("}\n"); //$NON-NLS-1$
- mBuildFile.append("\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs the beginning of an Android task in the build file.
- */
- private void startAndroidTask(ProjectState projectState) {
- int buildApi = projectState.getTarget().getVersion().getApiLevel();
- String toolsVersion = projectState.getTarget().getBuildToolInfo().getRevision().toString();
- mBuildFile.append("android {\n"); //$NON-NLS-1$
- mBuildFile.append(" compileSdkVersion " + buildApi + "\n"); //$NON-NLS-1$
- mBuildFile.append(" buildToolsVersion \"" + toolsVersion + "\"\n"); //$NON-NLS-1$
- mBuildFile.append("\n"); //$NON-NLS-1$
-
- try {
- IJavaProject javaProject = BaseProjectHelper.getJavaProject(projectState.getProject());
- // otherwise we check source compatibility
- String source = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
- if (JavaCore.VERSION_1_7.equals(source)) {
- mBuildFile.append(
- " compileOptions {\n" + //$NON-NLS-1$
- " sourceCompatibility JavaVersion.VERSION_1_7\n" + //$NON-NLS-1$
- " targetCompatibility JavaVersion.VERSION_1_7\n" + //$NON-NLS-1$
- " }\n" + //$NON-NLS-1$
- "\n"); //$NON-NLS-1$
- }
- } catch (CoreException e) {
- // Ignore compliance level, go with default
- }
- }
-
- /**
- * Outputs a sourceSets block to the Android task that locates all of the various source
- * subdirectories in the project.
- */
- private void createAndroidSourceSets() {
- IFolderWrapper projectFolder = new IFolderWrapper(mModule.getProject());
- IAbstractFile mManifestFile = AndroidManifest.getManifest(projectFolder);
- if (mManifestFile == null) {
- return;
- }
- List<String> srcDirs = new ArrayList<String>();
- for (IClasspathEntry entry : mModule.getJavaProject().readRawClasspath()) {
- if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE ||
- SdkConstants.FD_GEN_SOURCES.equals(entry.getPath().lastSegment())) {
- continue;
- }
- IPath path = entry.getPath().removeFirstSegments(1);
- srcDirs.add("'" + path.toOSString() + "'"); //$NON-NLS-1$
- }
-
- String srcPaths = Joiner.on(",").join(srcDirs);
-
- mBuildFile.append(" sourceSets {\n"); //$NON-NLS-1$
- mBuildFile.append(" main {\n"); //$NON-NLS-1$
- mBuildFile.append(" manifest.srcFile '" + SdkConstants.FN_ANDROID_MANIFEST_XML + "'\n"); //$NON-NLS-1$
- mBuildFile.append(" java.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" resources.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" aidl.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" renderscript.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" res.srcDirs = ['res']\n"); //$NON-NLS-1$
- mBuildFile.append(" assets.srcDirs = ['assets']\n"); //$NON-NLS-1$
- mBuildFile.append(" }\n"); //$NON-NLS-1$
- mBuildFile.append("\n"); //$NON-NLS-1$
- mBuildFile.append(" // Move the tests to tests/java, tests/res, etc...\n"); //$NON-NLS-1$
- mBuildFile.append(" instrumentTest.setRoot('tests')\n"); //$NON-NLS-1$
- if (srcDirs.contains("'src'")) {
- mBuildFile.append("\n"); //$NON-NLS-1$
- mBuildFile.append(" // Move the build types to build-types/<type>\n"); //$NON-NLS-1$
- mBuildFile.append(" // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...\n"); //$NON-NLS-1$
- mBuildFile.append(" // This moves them out of them default location under src/<type>/... which would\n"); //$NON-NLS-1$
- mBuildFile.append(" // conflict with src/ being used by the main source set.\n"); //$NON-NLS-1$
- mBuildFile.append(" // Adding new build types or product flavors should be accompanied\n"); //$NON-NLS-1$
- mBuildFile.append(" // by a similar customization.\n"); //$NON-NLS-1$
- mBuildFile.append(" debug.setRoot('build-types/debug')\n"); //$NON-NLS-1$
- mBuildFile.append(" release.setRoot('build-types/release')\n"); //$NON-NLS-1$
- }
- mBuildFile.append(" }\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs the completion of the Android task in the build file.
- */
- private void finishAndroidTask() {
- mBuildFile.append("}\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs a boilerplate header for non-Android projects
- */
- private void appendJavaHeader() {
- mBuildFile.append("apply plugin: 'java'\n"); //$NON-NLS-1$
- }
-
- /**
- * Outputs a sourceSets block for non-Android projects to locate the source directories.
- */
- private void createJavaSourceSets() {
- List<String> dirs = new ArrayList<String>();
- for (IClasspathEntry entry : mModule.getJavaProject().readRawClasspath()) {
- if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
- continue;
- }
- IPath path = entry.getPath().removeFirstSegments(1);
- dirs.add("'" + path.toOSString() + "'"); //$NON-NLS-1$
- }
-
- String srcPaths = Joiner.on(",").join(dirs);
-
- mBuildFile.append("sourceSets {\n"); //$NON-NLS-1$
- mBuildFile.append(" main.java.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" main.resources.srcDirs = [" + srcPaths + "]\n"); //$NON-NLS-1$
- mBuildFile.append(" test.java.srcDirs = ['tests/java']\n"); //$NON-NLS-1$
- mBuildFile.append(" test.resources.srcDirs = ['tests/resources']\n"); //$NON-NLS-1$
- mBuildFile.append("}\n"); //$NON-NLS-1$
- }
-
- /**
- * Merges the new subproject dependencies into the settings.gradle file if it already exists,
- * and creates one if it does not.
- * @throws IOException
- */
- private static void writeGradleSettingsFile(File settingsFile, List<String> projectPaths)
- throws IOException {
- StringBuilder contents = new StringBuilder();
- for (String path : projectPaths) {
- contents.append("include '").append(path).append("'\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- Files.write(contents.toString(), settingsFile, Charsets.UTF_8);
- }
-
- private static void writeRootBuildGradle(File buildFile) throws IOException {
- StringBuilder sb = new StringBuilder(
- "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n");
-
- appendBuildScript(sb);
-
- Files.write(sb.toString(), buildFile, Charsets.UTF_8);
- }
-
- /**
- * Request write access to given files. Depending on the version control
- * plug-in opens a confirm checkout dialog.
- *
- * @param shell
- * parent instance for dialogs
- * @return <code>IFile</code> objects for which user confirmed checkout
- * @throws CoreException
- * thrown if project is under version control, but not connected
- */
- static Set<IFile> validateEdit(
- @NonNull List<IFile> files,
- @NonNull ExportStatus exportStatus,
- @NonNull Shell shell) {
- Set<IFile> confirmedFiles = new TreeSet<IFile>(FILE_COMPARATOR);
- if (files.size() == 0) {
- return confirmedFiles;
- }
- IStatus status = (files.get(0)).getWorkspace().validateEdit(
- files.toArray(new IFile[files.size()]), shell);
- if (status.isMultiStatus() && status.getChildren().length > 0) {
- for (int i = 0; i < status.getChildren().length; i++) {
- IStatus statusChild = status.getChildren()[i];
- if (statusChild.isOK()) {
- confirmedFiles.add(files.get(i));
- } else {
- exportStatus.addFileStatus(
- ExportStatus.FileStatus.VCS_FAILURE,
- files.get(i).getLocation().toFile());
- }
- }
- } else if (status.isOK()) {
- confirmedFiles.addAll(files);
- }
- if (status.getSeverity() == IStatus.ERROR) {
- // not possible to checkout files: not connected to version
- // control plugin or hijacked files and made read-only, so
- // collect error messages provided by validator and re-throw
- StringBuffer message = new StringBuffer(status.getPlugin() + ": " //$NON-NLS-1$
- + status.getMessage() + NEWLINE);
- if (status.isMultiStatus()) {
- for (int i = 0; i < status.getChildren().length; i++) {
- IStatus statusChild = status.getChildren()[i];
- message.append(statusChild.getMessage() + NEWLINE);
- }
- }
- String s = message.toString();
- exportStatus.setErrorMessage(s);
- }
-
- return confirmedFiles;
- }
-
- // -------------------------------------------------------------------------------
- // Fix gradle wrapper version. This code is from GradleUtil in the Studio plugin:
- // -------------------------------------------------------------------------------
-
- private static final String GRADLE_PROPERTIES = "gradle-wrapper.properties";
- private static final String GRADLEW_PROPERTIES_PATH =
- "gradle" + File.separator + "wrapper" + File.separator + GRADLE_PROPERTIES;
- private static final String GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME = "distributionUrl";
-
- @NonNull
- private static File getGradleWrapperPropertiesFilePath(@NonNull File projectRootDir) {
- return new File(projectRootDir, GRADLEW_PROPERTIES_PATH);
- }
-
- @Nullable
- public static File findWrapperPropertiesFile(@NonNull File projectRootDir) {
- File wrapperPropertiesFile = getGradleWrapperPropertiesFilePath(projectRootDir);
- return wrapperPropertiesFile.isFile() ? wrapperPropertiesFile : null;
- }
-
- private static boolean updateGradleDistributionUrl(
- @NonNull String gradleVersion,
- @NonNull File propertiesFile) throws IOException {
- Properties properties = loadGradleWrapperProperties(propertiesFile);
- String gradleDistributionUrl = getGradleDistributionUrl(gradleVersion, false);
- String property = properties.getProperty(GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME);
- if (property != null
- && (property.equals(gradleDistributionUrl) || property
- .equals(getGradleDistributionUrl(gradleVersion, true)))) {
- return false;
- }
- properties.setProperty(GRADLEW_DISTRIBUTION_URL_PROPERTY_NAME, gradleDistributionUrl);
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(propertiesFile);
- properties.store(out, null);
- return true;
- } finally {
- Closeables.close(out, true);
- }
- }
-
- @NonNull
- private static Properties loadGradleWrapperProperties(@NonNull File propertiesFile)
- throws IOException {
- Properties properties = new Properties();
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(propertiesFile);
- properties.load(fileInputStream);
- return properties;
- } finally {
- Closeables.close(fileInputStream, true);
- }
- }
-
- @NonNull
- private static String getGradleDistributionUrl(@NonNull String gradleVersion,
- boolean binOnly) {
- String suffix = binOnly ? "bin" : "all";
- return String.format("https://services.gradle.org/distributions/gradle-%1$s-" + suffix
- + ".zip", gradleVersion);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ConfirmationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ConfirmationPage.java
deleted file mode 100644
index 1f236fb2b..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ConfirmationPage.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.google.common.collect.Lists;
-
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableLayout;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.ui.model.WorkbenchLabelProvider;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Confirmation page to review the actual project export
- * list and see warning about existing files.
- *
- */
-public class ConfirmationPage extends WizardPage {
-
- private final ProjectSetupBuilder mBuilder;
- private TableViewer mTableViewer;
- private Label mModuleDescription1;
- private Label mModuleDescription2;
- private Label mModuleDescription3;
- private Label mProjectRootLabel;
- private Label mProjectRootWarning;
- private List<IJavaProject> mOverrideProjects;
- private boolean mOverrideWarning;
- private Button mForceOverride;
-
- public ConfirmationPage(ProjectSetupBuilder builder) {
- super("ConfirmationPage"); //$NON-NLS-1$
- mBuilder = builder;
- setPageComplete(false);
- setTitle(ExportMessages.PageTitle);
- setDescription(ExportMessages.PageDescription);
- }
-
- @Override
- public void createControl(Composite parent) {
- initializeDialogUnits(parent);
- GridData data;
-
- Composite workArea = new Composite(parent, SWT.NONE);
- setControl(workArea);
-
- workArea.setLayout(new GridLayout());
- workArea.setLayoutData(new GridData(GridData.FILL_BOTH
- | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
-
- Label title = new Label(workArea, SWT.NONE);
- title.setText("Please review the export options.");
-
- Group group = new Group(workArea, SWT.NONE);
- group.setText("Project root");
- group.setLayout(new GridLayout());
- group.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
-
- mProjectRootLabel = new Label(group, SWT.NONE);
- mProjectRootLabel.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
-
- mProjectRootWarning = new Label(group, SWT.NONE);
- mProjectRootWarning.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
-
- Group group2 = new Group(workArea, SWT.NONE);
- group2.setText("Exported Modules");
- group2.setLayout(new GridLayout());
- group2.setLayoutData(data = new GridData(SWT.FILL, SWT.FILL, true, true));
- data.heightHint = 300;
-
- Table table = new Table(group2, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- mTableViewer = new TableViewer(table);
- table.setLayout(new TableLayout());
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- mTableViewer.setContentProvider(new IStructuredContentProvider() {
- @Override
- public Object[] getElements(Object inputElement) {
- if (inputElement instanceof ProjectSetupBuilder) {
- ProjectSetupBuilder builder = (ProjectSetupBuilder) inputElement;
- Collection<GradleModule> modules = builder.getModules();
- Object[] array = new Object[modules.size()];
- int i = 0;
- for (GradleModule module : modules) {
- array[i++] = module.getJavaProject();
- }
-
- return array;
- }
-
- return null;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- });
- mTableViewer.setLabelProvider(new WorkbenchLabelProvider() {
- @Override
- protected String decorateText(String input, Object element) {
- if (element instanceof IJavaProject) {
- IJavaProject javaProject = (IJavaProject) element;
- StringBuilder sb = new StringBuilder(input);
- if (!mBuilder.isOriginalProject(javaProject)) {
- sb.append('*');
- }
- // TODO: decorate icon instead?
- if (mOverrideProjects.contains(javaProject)) {
- sb.append(" (1 warning)");
- }
-
- return sb.toString();
- }
-
- return input;
- }
- });
- mTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- IStructuredSelection selection = (IStructuredSelection) event.getSelection();
- Object firstElement = selection.getFirstElement();
- if (firstElement instanceof IJavaProject) {
- GradleModule module = mBuilder.getModule((IJavaProject) firstElement);
- if (mBuilder.getOriginalModules().contains(module)) {
- mModuleDescription1.setText("Exported because selected in previous page.");
- } else {
- List<GradleModule> list = mBuilder.getShortestDependencyTo(module);
- StringBuilder sb = new StringBuilder();
- for (GradleModule m : list) {
- if (sb.length() > 0) {
- sb.append(" > ");
- }
- sb.append(m.getJavaProject().getProject().getName());
- }
- mModuleDescription1.setText("Dependency chain: " + sb);
- }
- mModuleDescription2.setText("Path: " + module.getPath());
-
- if (mOverrideProjects.contains(module.getJavaProject())) {
- mModuleDescription3.setText(
- "WARNING: build.gradle already exists for this project");
- } else {
- mModuleDescription3.setText("");
- }
- } else {
- mModuleDescription1.setText("");
- mModuleDescription2.setText("");
- mModuleDescription3.setText("");
- }
- }
- });
-
- mModuleDescription1 = new Label(group2, SWT.NONE);
- mModuleDescription1.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
- mModuleDescription2 = new Label(group2, SWT.NONE);
- mModuleDescription2.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
- mModuleDescription3 = new Label(group2, SWT.NONE);
- mModuleDescription3.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
-
- mForceOverride = new Button(workArea, SWT.CHECK);
- mForceOverride.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
- mForceOverride.setText("Force overriding of existing files");
- mForceOverride.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- updateEnablement();
- }
- });
-
- setControl(workArea);
- Dialog.applyDialogFont(parent);
- }
-
- /**
- * Get list of projects which have already a buildfile.
- *
- * @param javaProjects list of IJavaProject objects
- * @return set of project names
- */
- private void computeOverride(String commonRoot) {
- mOverrideProjects = Lists.newArrayList();
- for (GradleModule module : mBuilder.getModules()) {
- if (new File(module.getProject().getLocation().toFile(),
- BuildFileCreator.BUILD_FILE).exists()) {
- mOverrideProjects.add(module.getJavaProject());
- }
- }
-
- // also check on the root settings.gradle/build.gradle
- boolean settingsFile = new File(commonRoot, BuildFileCreator.SETTINGS_FILE).exists();
- boolean buildFile = new File(commonRoot, BuildFileCreator.BUILD_FILE).exists();
- if (settingsFile && buildFile) {
- mProjectRootWarning.setText(
- "WARNING: build.gradle/settings.gradle already exists at this location.");
- } else if (settingsFile) {
- mProjectRootWarning.setText(
- "WARNING: settings.gradle already exists at this location.");
- } else if (buildFile) {
- mProjectRootWarning.setText("WARNING: build.gradle already exists at this location.");
- }
-
- mOverrideWarning = mOverrideProjects.size() > 0 || settingsFile || buildFile;
- }
-
- /**
- * Enables/disables the finish button on the wizard and displays error messages as needed.
- */
- private void updateEnablement() {
- if (mOverrideWarning && !mForceOverride.getSelection()) {
- setErrorMessage("Enable overriding of existing files before clicking Finish");
- mBuilder.setCanGenerate(false);
- } else {
- setErrorMessage(null);
- mBuilder.setCanGenerate(true);
- }
- setPageComplete(false);
- getContainer().updateButtons();
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- mProjectRootWarning.setText("");
-
- String commonRoot = mBuilder.getCommonRoot().toOSString();
- computeOverride(commonRoot);
- mProjectRootLabel.setText(commonRoot);
- mTableViewer.setInput(mBuilder);
- mTableViewer.getTable().setFocus();
- mBuilder.setCanFinish(false);
- mBuilder.setCanGenerate(true);
- updateEnablement();
- }
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.java
deleted file mode 100644
index c7d6c1748..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import org.eclipse.osgi.util.NLS;
-
-public class ExportMessages extends NLS {
- private static final String BUNDLE_NAME =
- "com.android.ide.eclipse.adt.internal.wizards.exportgradle.ExportMessages";//$NON-NLS-1$
-
- public static String PageTitle;
- public static String PageDescription;
- public static String SelectProjects;
- public static String ConfirmOverwrite;
- public static String ConfirmOverwriteTitle;
- public static String CyclicProjectsError;
- public static String ExportFailedError;
- public static String SelectAll;
- public static String DeselectAll;
- public static String NoProjectsError;
- public static String StatusMessage;
- public static String FileStatusMessage;
- public static String WindowTitle;
-
- static {
- // load message values from bundle file
- NLS.initializeMessages(BUNDLE_NAME, ExportMessages.class);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.properties b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.properties
deleted file mode 100644
index 1a6dbb192..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportMessages.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2013 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.
-
-PageTitle=Generate Gradle Build files
-PageDescription=Generates Gradle build files based on the configuration of the Java projects
-SelectProjects=Select the projects to use to &generate the Gradle buildfiles:
-ConfirmOverwrite=Are you sure you want to overwrite the buildfiles for these projects?
-ConfirmOverwriteTitle=Overwrite Buildfiles?
-CyclicProjectsError=A cycle was detected in the build path of project: {0}
-ExportFailedError=Buildfile export failed: {0}. See the error log for more details.
-SelectAll=&Select All
-DeselectAll=&Deselect All
-NoProjectsError=Select one or more projects to export.
-StatusMessage=Creating Gradle build files...
-FileStatusMessage=Generating build file for {0}...
-WindowTitle=Export \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportStatus.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportStatus.java
deleted file mode 100644
index 6fbe14e42..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ExportStatus.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-
-import java.io.File;
-
-public class ExportStatus {
-
- public static enum FileStatus { OK, VCS_FAILURE, IO_FAILURE; }
-
- private String mMainError = null;
- private final Multimap<FileStatus, File> mFileStatus = ArrayListMultimap.create();
-
- void addFileStatus(@NonNull FileStatus status, @NonNull File file) {
- mFileStatus.put(status, file);
- }
-
- boolean hasError() {
- return mMainError != null ||
- !mFileStatus.get(FileStatus.VCS_FAILURE).isEmpty() ||
- !mFileStatus.get(FileStatus.IO_FAILURE).isEmpty();
- }
-
- public void setErrorMessage(String error) {
- mMainError = error;
- }
-
- @Nullable
- public String getErrorMessage() {
- return mMainError;
- }
-
- @NonNull
- public Multimap<FileStatus, File> getFileStatus() {
- return mFileStatus;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/FinalPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/FinalPage.java
deleted file mode 100644
index bbfadf855..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/FinalPage.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.android.ide.eclipse.adt.internal.wizards.exportgradle.ExportStatus.FileStatus;
-import com.google.common.collect.Multimap;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-import java.util.Collection;
-
-/**
- * Final page to review the result of the export.
- */
-public class FinalPage extends WizardPage {
-
- private final ProjectSetupBuilder mBuilder;
- private ExportStatus mStatus;
-
- private Text mText;
-
- public FinalPage(ProjectSetupBuilder builder) {
- super("FinalPage"); //$NON-NLS-1$
- mBuilder = builder;
- setPageComplete(true);
- setTitle(ExportMessages.PageTitle);
- setDescription(ExportMessages.PageDescription);
- }
-
- @Override
- public void createControl(Composite parent) {
- initializeDialogUnits(parent);
-
- mText = new Text(parent, SWT.MULTI | SWT.READ_ONLY);
- mText.setLayoutData(new GridData(GridData.FILL_BOTH
- | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
-
- setControl(mText);
- Dialog.applyDialogFont(parent);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- mStatus = mBuilder.getStatus();
- mBuilder.setCanFinish(!mStatus.hasError());
- mBuilder.setCanGenerate(false);
-
- StringBuilder sb = new StringBuilder();
- if (mStatus.hasError()) {
- sb.append("There was an error!").append("\n\n");
-
- String errorMsg = mStatus.getErrorMessage();
- if (errorMsg != null) {
- sb.append(errorMsg);
- }
-
- Multimap<FileStatus, File> fileStatusMap = mStatus.getFileStatus();
- Collection<File> files = fileStatusMap.values();
- if (files != null) {
- sb.append("\n\n").append("Error on files:").append('\n');
- for (File file : files) {
- sb.append("\n").append(file.getAbsolutePath());
- }
- }
- } else {
- sb.append("Export successful.\n\n");
-
- int count = mBuilder.getModuleCount();
- if (count > 1) {
- sb.append(String.format("Exported %s modules", count)).append('\n');
- sb.append(String.format(
- "Root folder: %s", mBuilder.getCommonRoot().toOSString()));
- } else {
- sb.append("Exported project: ").append(mBuilder.getCommonRoot().toOSString());
- }
-
- sb.append("\n\n").append("Choose 'Import Non-Android Studio project' in Android Studio").append('\n');
- sb.append("and select the following file:").append("\n\t");
-
- File bGradle = new File(
- mBuilder.getCommonRoot().toFile(), BuildFileCreator.BUILD_FILE);
- sb.append(bGradle.getAbsolutePath());
-
- sb.append("\n\n").append("Do NOT import the Eclipse project itself!");
- }
-
- mText.setText(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/exportgradle/GradleExportWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleExportWizard.java
deleted file mode 100644
index 8c74187ff..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleExportWizard.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.ui.IExportWizard;
-import org.eclipse.ui.IWorkbench;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-
-public class GradleExportWizard extends Wizard implements IExportWizard {
-
- private ProjectSetupBuilder mBuilder = new ProjectSetupBuilder();
-
- private ProjectSelectionPage mFirstPage;
- private ConfirmationPage mSecondPage;
- private FinalPage mFinalPage;
-
- /**
- * Creates buildfile.
- */
- @Override
- public boolean performFinish() {
- if (mBuilder.canGenerate()) {
- generateBuildfiles(mSecondPage);
- getContainer().showPage(mFinalPage);
- return false;
- }
-
- return true;
- }
-
- @Override
- public void addPages() {
- addPage(new ImportInsteadPage());
- mFirstPage = new ProjectSelectionPage(mBuilder);
- addPage(mFirstPage);
- mSecondPage = new ConfirmationPage(mBuilder);
- addPage(mSecondPage);
- mFinalPage = new FinalPage(mBuilder);
- addPage(mFinalPage);
- }
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- setWindowTitle(ExportMessages.WindowTitle);
- setNeedsProgressMonitor(true);
- }
-
- @Override
- public boolean canFinish() {
- return mBuilder.canFinish() || mBuilder.canGenerate();
- }
-
- /**
- * Converts Eclipse Java projects to Gradle build files. Displays error dialogs.
- */
- public boolean generateBuildfiles(final WizardPage page) {
- IRunnableWithProgress runnable = new IRunnableWithProgress() {
- @Override
- public void run(IProgressMonitor pm) throws InterruptedException {
- Collection<GradleModule> modules = mBuilder.getModules();
- final int count = modules.size();
-
- SubMonitor localmonitor = SubMonitor.convert(pm, ExportMessages.StatusMessage,
- count);
- BuildFileCreator.createBuildFiles(
- mBuilder,
- page.getShell(),
- localmonitor.newChild(count));
- }
- };
-
- try {
- getContainer().run(false, false, runnable);
- } catch (InvocationTargetException e) {
- AdtPlugin.log(e, null);
- return false;
- } catch (InterruptedException e) {
- AdtPlugin.log(e, null);
- return false;
- }
- if (page.getErrorMessage() != null) {
- return false;
- }
- return true;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleModule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleModule.java
deleted file mode 100644
index 684f03b9a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/GradleModule.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.android.annotations.NonNull;
-import com.google.common.collect.Lists;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.jdt.core.IJavaProject;
-
-import java.util.List;
-
-/**
- * A configured Gradle module for export. This includes gradle path, dependency, type, etc...
- */
-public class GradleModule {
-
- @NonNull
- private final IJavaProject mJavaProject;
-
- private String mPath;
- private Type mType;
-
- private final List<GradleModule> mDependencies = Lists.newArrayList();
-
- public static enum Type { ANDROID, JAVA };
-
- GradleModule(@NonNull IJavaProject javaProject) {
- mJavaProject = javaProject;
- }
-
- @NonNull
- public IJavaProject getJavaProject() {
- return mJavaProject;
- }
-
- @NonNull
- public IProject getProject() {
- return mJavaProject.getProject();
- }
-
- boolean isConfigured() {
- return mType != null;
- }
-
- public void setType(Type type) {
- mType = type;
- }
-
- public Type getType() {
- return mType;
- }
-
- public void addDependency(GradleModule module) {
- mDependencies.add(module);
- }
-
- public List<GradleModule> getDependencies() {
- return mDependencies;
- }
-
- public void setPath(String path) {
- mPath = path;
- }
-
- public String getPath() {
- return mPath;
- }
-
- @Override
- public String toString() {
- return "GradleModule [mJavaProject=" + mJavaProject + ", mPath=" + mPath + ", mType="
- + mType + ", mDependencies=" + mDependencies + "]";
- }
-}
-
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ImportInsteadPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ImportInsteadPage.java
deleted file mode 100644
index cff9aca63..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ImportInsteadPage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2014 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.exportgradle;
-
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-
-class ImportInsteadPage extends WizardPage {
- public ImportInsteadPage() {
- super("importInstead");
- setTitle("Import Instead?");
- setDescription("Consider importing directly into Android Studio instead of exporting from Eclipse");
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
- setControl(container);
- container.setLayout(new GridLayout(1, false));
-
- CLabel label = new CLabel(container, SWT.NONE);
- label.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1));
- label.setText(
- "Recent versions of Android Studio now support direct import of ADT projects.\n" +
- "\n" +
- "There are advantages to importing from Studio instead of exporting from Eclipse:\n" +
- "- It can replace jars and library projects with Gradle dependencies instead\n" +
- "- On import, it creates a new copy of the project and changes the project structure\n" +
- " to the new Gradle directory layout which better supports multiple resource directories.\n" +
- "- It can merge instrumentation test projects into the same project\n" +
- "- Android Studio is released more frequently than the ADT plugin, so the import\n" +
- " mechanism more closely tracks the requirements of Studio Gradle projects.\n" +
- "\n" +
- "If you want to preserve your Eclipse directory structure, or if for some reason import\n" +
- "in Studio doesn't work (please let us know by filing a bug), continue to export from\n" +
- "Eclipse instead.");
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java
deleted file mode 100644
index 81c7a7346..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.ibm.icu.text.MessageFormat;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaModelMarker;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ICheckStateListener;
-import org.eclipse.jface.viewers.TableLayout;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Table;
-import org.eclipse.ui.model.WorkbenchContentProvider;
-import org.eclipse.ui.model.WorkbenchLabelProvider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Displays a wizard page that lets the user choose the projects for which to create Gradle build
- * files.
- * <p>
- * Based on {@link org.eclipse.ant.internal.ui.datatransfer.AntBuildfileExportPage}
- */
-public class ProjectSelectionPage extends WizardPage {
-
- private final ProjectSetupBuilder mBuilder;
- private CheckboxTableViewer mTableViewer;
- private List<IJavaProject> mSelectedJavaProjects = Lists.newArrayList();
-
- public ProjectSelectionPage(ProjectSetupBuilder builder) {
- super("GradleExportPage"); //$NON-NLS-1$
- mBuilder = builder;
- setPageComplete(false);
- setTitle(ExportMessages.PageTitle);
- setDescription(ExportMessages.PageDescription);
- }
-
- @Override
- public void createControl(Composite parent) {
- initializeDialogUnits(parent);
-
- Composite workArea = new Composite(parent, SWT.NONE);
- setControl(workArea);
-
- workArea.setLayout(new GridLayout());
- workArea.setLayoutData(new GridData(GridData.FILL_BOTH
- | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
-
- Label title = new Label(workArea, SWT.NONE);
- title.setText(ExportMessages.SelectProjects);
-
- Composite listComposite = new Composite(workArea, SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.numColumns = 2;
- layout.marginWidth = 0;
- layout.makeColumnsEqualWidth = false;
- listComposite.setLayout(layout);
-
- listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
- | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
-
- Table table = new Table(listComposite,
- SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- mTableViewer = new CheckboxTableViewer(table);
- table.setLayout(new TableLayout());
- GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
- data.heightHint = 300;
- table.setLayoutData(data);
- mTableViewer.setContentProvider(new WorkbenchContentProvider() {
- @Override
- public Object[] getElements(Object element) {
- if (element instanceof IJavaProject[]) {
- return (IJavaProject[]) element;
- }
- return null;
- }
- });
- mTableViewer.setLabelProvider(new WorkbenchLabelProvider());
- mTableViewer.addCheckStateListener(new ICheckStateListener() {
- @Override
- public void checkStateChanged(CheckStateChangedEvent event) {
- if (event.getChecked()) {
- mSelectedJavaProjects.add((IJavaProject) event.getElement());
- } else {
- mSelectedJavaProjects.remove(event.getElement());
- }
- updateEnablement();
- }
- });
-
- initializeProjects();
- createSelectionButtons(listComposite);
- setControl(workArea);
- updateEnablement();
- Dialog.applyDialogFont(parent);
- }
-
- /**
- * Creates select all/deselect all buttons.
- */
- private void createSelectionButtons(Composite composite) {
- Composite buttonsComposite = new Composite(composite, SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- buttonsComposite.setLayout(layout);
-
- buttonsComposite.setLayoutData(new GridData(
- GridData.VERTICAL_ALIGN_BEGINNING));
-
- Button selectAll = new Button(buttonsComposite, SWT.PUSH);
- selectAll.setText(ExportMessages.SelectAll);
- selectAll.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- for (int i = 0; i < mTableViewer.getTable().getItemCount(); i++) {
- mSelectedJavaProjects.add((IJavaProject) mTableViewer.getElementAt(i));
- }
- mTableViewer.setAllChecked(true);
- updateEnablement();
- }
- });
- setButtonLayoutData(selectAll);
-
- Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
- deselectAll.setText(ExportMessages.DeselectAll);
- deselectAll.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- mSelectedJavaProjects.clear();
- mTableViewer.setAllChecked(false);
- updateEnablement();
- }
- });
- setButtonLayoutData(deselectAll);
- }
-
- /**
- * Populates the list with all the eligible projects in the workspace.
- */
- private void initializeProjects() {
- IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot();
- IJavaModel javaModel = JavaCore.create(rootWorkspace);
- IJavaProject[] javaProjects;
- try {
- javaProjects = javaModel.getJavaProjects();
- } catch (JavaModelException e) {
- javaProjects = new IJavaProject[0];
- }
- mTableViewer.setInput(javaProjects);
- // Check any necessary projects
- if (mSelectedJavaProjects != null) {
- mTableViewer.setCheckedElements(mSelectedJavaProjects.toArray(
- new IJavaProject[mSelectedJavaProjects.size()]));
- }
- }
-
- /**
- * Enables/disables the finish button on the wizard and displays error messages as needed.
- */
- private void updateEnablement() {
- String error = null;
- try {
- if (mSelectedJavaProjects.size() == 0) {
- error = ExportMessages.NoProjectsError;
- return;
- }
-
- List<String> cyclicProjects;
- try {
- cyclicProjects = getCyclicProjects(mSelectedJavaProjects);
- if (cyclicProjects.size() > 0) {
- error = MessageFormat.format(ExportMessages.CyclicProjectsError,
- new Object[] { Joiner.on(", ").join(cyclicProjects) }); //$NON-NLS-1$
- return;
- }
-
- error = mBuilder.setProject(mSelectedJavaProjects);
- if (error != null) {
- return;
- }
-
- } catch (CoreException ignored) {
- // TODO: do something?
- }
- } finally {
- setErrorMessage(error);
- setPageComplete(error == null);
- getContainer().updateButtons();
- }
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- mTableViewer.getTable().setFocus();
- mBuilder.setCanFinish(false);
- mBuilder.setCanGenerate(false);
- }
- }
-
- /**
- * Returns given projects that have cyclic dependencies.
- *
- * @param javaProjects list of IJavaProject objects
- * @return set of project names
- */
- private List<String> getCyclicProjects(List<IJavaProject> projects) throws CoreException {
-
- List<String> cyclicProjects = new ArrayList<String>();
- for (IJavaProject javaProject : projects) {
- if (hasCyclicDependency(javaProject)) {
- cyclicProjects.add(javaProject.getProject().getName());
- }
- }
- return cyclicProjects;
- }
-
- /**
- * Check if given project has a cyclic dependency.
- * <p>
- * See {@link org.eclipse.jdt.core.tests.model.ClasspathTests.numberOfCycleMarkers}
- */
- private static boolean hasCyclicDependency(IJavaProject javaProject)
- throws CoreException {
- IMarker[] markers = javaProject.getProject().findMarkers(
- IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false,
- IResource.DEPTH_ONE);
- for (IMarker marker : markers) {
- String cycleAttr = (String) marker
- .getAttribute(IJavaModelMarker.CYCLE_DETECTED);
- if (cycleAttr != null && cycleAttr.equals("true")) { //$NON-NLS-1$
- return true;
- }
- }
- return false;
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSetupBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSetupBuilder.java
deleted file mode 100644
index 1fd6b74f6..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSetupBuilder.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2013 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.exportgradle;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState.LibraryState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import org.eclipse.core.resources.IProject;
-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.Path;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * Class to setup the project and its modules.
- */
-public class ProjectSetupBuilder {
-
- private final static class InternalException extends Exception {
- private static final long serialVersionUID = 1L;
-
- InternalException(String message) {
- super(message);
- }
- }
-
- private boolean mCanFinish = false;
- private boolean mCanGenerate = false;
- private final List<GradleModule> mOriginalModules = Lists.newArrayList();
- private final Map<IJavaProject, GradleModule> mModules = Maps.newHashMap();
- private IPath mCommonRoot;
- private ExportStatus mStatus;
-
- public ProjectSetupBuilder() {
-
- }
-
- public void setCanGenerate(boolean generate) {
- mCanGenerate = generate;
- }
-
- public void setCanFinish(boolean canFinish) {
- mCanFinish = canFinish;
- }
-
- public boolean canFinish() {
- return mCanFinish;
- }
-
- public boolean canGenerate() {
- return mCanGenerate;
- }
-
- public void setStatus(ExportStatus status) {
- mStatus = status;
- }
-
- public ExportStatus getStatus() {
- return mStatus;
- }
-
- @NonNull
- public String setProject(@NonNull List<IJavaProject> selectedProjects)
- throws CoreException {
- mModules.clear();
-
- // build a list of all projects that must be included. This is in case
- // some dependencies have not been included in the selected projects. We also include
- // parent projects so that the full multi-project setup is correct.
- // Note that if two projects are selected that are not related, both will be added
- // in the same multi-project anyway.
- try {
- for (IJavaProject javaProject : selectedProjects) {
- GradleModule module;
-
- if (javaProject.getProject().hasNature(AdtConstants.NATURE_DEFAULT)) {
- module = processAndroidProject(javaProject);
- } else {
- module = processJavaProject(javaProject);
- }
-
- mOriginalModules.add(module);
- }
-
- Collection<GradleModule> modules = mModules.values();
- computeRootAndPaths(modules);
-
- return null;
- } catch (InternalException e) {
- return e.getMessage();
- }
- }
-
- @NonNull
- public Collection<GradleModule> getModules() {
- return mModules.values();
- }
-
- public int getModuleCount() {
- return mModules.size();
- }
-
- @Nullable
- public IPath getCommonRoot() {
- return mCommonRoot;
- }
-
- @Nullable
- public GradleModule getModule(IJavaProject javaProject) {
- return mModules.get(javaProject);
- }
-
- public boolean isOriginalProject(@NonNull IJavaProject javaProject) {
- GradleModule module = mModules.get(javaProject);
- return mOriginalModules.contains(module);
- }
-
- @NonNull
- public List<GradleModule> getOriginalModules() {
- return mOriginalModules;
- }
-
- @Nullable
- public List<GradleModule> getShortestDependencyTo(GradleModule module) {
- return findModule(module, mOriginalModules);
- }
-
- @Nullable
- public List<GradleModule> findModule(GradleModule toFind, GradleModule rootModule) {
- if (toFind == rootModule) {
- List<GradleModule> list = Lists.newArrayList();
- list.add(toFind);
- return list;
- }
-
- List<GradleModule> shortestChain = findModule(toFind, rootModule.getDependencies());
-
- if (shortestChain != null) {
- shortestChain.add(0, rootModule);
- }
-
- return shortestChain;
- }
-
- @Nullable
- public List<GradleModule> findModule(GradleModule toFind, List<GradleModule> modules) {
- List<GradleModule> currentChain = null;
-
- for (GradleModule child : modules) {
- List<GradleModule> newChain = findModule(toFind, child);
- if (currentChain == null) {
- currentChain = newChain;
- } else if (newChain != null) {
- if (currentChain.size() > newChain.size()) {
- currentChain = newChain;
- }
- }
- }
-
- return currentChain;
- }
-
- @NonNull
- private GradleModule processAndroidProject(@NonNull IJavaProject javaProject)
- throws InternalException, CoreException {
-
- // get/create the module
- GradleModule module = createModuleOnDemand(javaProject);
- if (module.isConfigured()) {
- return module;
- }
-
- module.setType(GradleModule.Type.ANDROID);
-
- ProjectState projectState = Sdk.getProjectState(javaProject.getProject());
- assert projectState != null;
-
- // add library project dependencies
- List<LibraryState> libraryProjects = projectState.getLibraries();
- for (LibraryState libraryState : libraryProjects) {
- ProjectState libProjectState = libraryState.getProjectState();
- if (libProjectState != null) {
- IJavaProject javaLib = getJavaProject(libProjectState);
- if (javaLib != null) {
- GradleModule libModule = processAndroidProject(javaLib);
- module.addDependency(libModule);
- } else {
- throw new InternalException(String.format(
- "Project %1$s is missing. Needed by %2$s.\n" +
- "Make sure all dependencies are opened.",
- libraryState.getRelativePath(),
- javaProject.getProject().getName()));
- }
- } else {
- throw new InternalException(String.format(
- "Project %1$s is missing. Needed by %2$s.\n" +
- "Make sure all dependencies are opened.",
- libraryState.getRelativePath(),
- javaProject.getProject().getName()));
- }
- }
-
- // add java project dependencies
- List<IJavaProject> javaDepProjects = getReferencedProjects(javaProject);
- for (IJavaProject javaDep : javaDepProjects) {
- GradleModule libModule = processJavaProject(javaDep);
- module.addDependency(libModule);
- }
-
- return module;
- }
-
- @NonNull
- private GradleModule processJavaProject(@NonNull IJavaProject javaProject)
- throws InternalException, CoreException {
- // get/create the module
- GradleModule module = createModuleOnDemand(javaProject);
-
- if (module.isConfigured()) {
- return module;
- }
-
- module.setType(GradleModule.Type.JAVA);
-
- // add java project dependencies
- List<IJavaProject> javaDepProjects = getReferencedProjects(javaProject);
- for (IJavaProject javaDep : javaDepProjects) {
- // Java project should not reference Android project!
- if (javaDep.getProject().hasNature(AdtConstants.NATURE_DEFAULT)) {
- throw new InternalException(String.format(
- "Java project %1$s depends on Android project %2$s!\n" +
- "This is not a valid dependency",
- javaProject.getProject().getName(), javaDep.getProject().getName()));
- }
- GradleModule libModule = processJavaProject(javaDep);
- module.addDependency(libModule);
- }
-
- return module;
- }
-
- private void computeRootAndPaths(Collection<GradleModule> modules) throws InternalException {
- // compute the common root.
- mCommonRoot = determineCommonRoot(modules);
-
- // compute all the relative paths.
- for (GradleModule module : modules) {
- String path = getGradlePath(module.getJavaProject().getProject().getLocation(),
- mCommonRoot);
-
- module.setPath(path);
- }
- }
-
- /**
- * Finds the common parent directory shared by this project and all its dependencies.
- * If there's only one project, returns the single project's folder.
- * @throws InternalException
- */
- @NonNull
- private static IPath determineCommonRoot(Collection<GradleModule> modules)
- throws InternalException {
- IPath commonRoot = null;
- for (GradleModule module : modules) {
- if (commonRoot == null) {
- commonRoot = module.getJavaProject().getProject().getLocation();
- } else {
- commonRoot = findCommonRoot(commonRoot,
- module.getJavaProject().getProject().getLocation());
- }
- }
-
- return commonRoot;
- }
-
- /**
- * Converts the given path to be relative to the given root path, and converts it to
- * Gradle project notation, such as is used in the settings.gradle file.
- */
- @NonNull
- private static String getGradlePath(IPath path, IPath root) {
- IPath relativePath = path.makeRelativeTo(root);
- String relativeString = relativePath.toOSString();
- return ":" + relativeString.replaceAll(Pattern.quote(File.separator), ":"); //$NON-NLS-1$
- }
-
- /**
- * Given two IPaths, finds the parent directory of both of them.
- * @throws InternalException
- */
- @NonNull
- private static IPath findCommonRoot(@NonNull IPath path1, @NonNull IPath path2)
- throws InternalException {
- if (path1.getDevice() != null && !path1.getDevice().equals(path2.getDevice())) {
- throw new InternalException(
- "Different modules have been detected on different drives.\n" +
- "This prevents finding a common root to all modules.");
- }
-
- IPath result = path1.uptoSegment(0);
-
- final int count = Math.min(path1.segmentCount(), path2.segmentCount());
- for (int i = 0; i < count; i++) {
- if (path1.segment(i).equals(path2.segment(i))) {
- result = result.append(Path.SEPARATOR + path2.segment(i));
- }
- }
- return result;
- }
-
- @Nullable
- private IJavaProject getJavaProject(ProjectState projectState) {
- try {
- return BaseProjectHelper.getJavaProject(projectState.getProject());
- } catch (CoreException e) {
- return null;
- }
- }
-
- @NonNull
- private GradleModule createModuleOnDemand(@NonNull IJavaProject javaProject) {
- GradleModule module = mModules.get(javaProject);
- if (module == null) {
- module = new GradleModule(javaProject);
- mModules.put(javaProject, module);
- }
-
- return module;
- }
-
- @NonNull
- private static List<IJavaProject> getReferencedProjects(IJavaProject javaProject)
- throws JavaModelException, InternalException {
-
- List<IJavaProject> projects = Lists.newArrayList();
-
- IClasspathEntry entries[] = javaProject.getRawClasspath();
- for (IClasspathEntry classpathEntry : entries) {
- if (classpathEntry.getContentKind() == IPackageFragmentRoot.K_SOURCE
- && classpathEntry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
- // found required project on build path
- String subProjectRoot = classpathEntry.getPath().toString();
- IJavaProject subProject = getJavaProject(subProjectRoot);
- // is project available in workspace?
- if (subProject != null) {
- projects.add(subProject);
- } else {
- throw new InternalException(String.format(
- "Project '%s' is missing project dependency '%s' in Eclipse workspace.\n" +
- "Make sure all dependencies are opened.",
- javaProject.getProject().getName(),
- classpathEntry.getPath().toString()));
- }
- }
- }
-
- return projects;
- }
-
- /**
- * Get Java project for given root.
- */
- @Nullable
- private static IJavaProject getJavaProject(String root) {
- IPath path = new Path(root);
- if (path.segmentCount() == 1) {
- return getJavaProjectByName(root);
- }
- IResource resource = ResourcesPlugin.getWorkspace().getRoot()
- .findMember(path);
- if (resource != null && resource.getType() == IResource.PROJECT) {
- if (resource.exists()) {
- return (IJavaProject) JavaCore.create(resource);
- }
- }
- return null;
- }
-
- /**
- * Get Java project from resource.
- */
- private static IJavaProject getJavaProjectByName(String name) {
- try {
- IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
- if (project.exists()) {
- return JavaCore.create(project);
- }
- } catch (IllegalArgumentException iae) {
- }
- return null;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java
deleted file mode 100644
index c8325345a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IProject;
-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.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.JavaConventions;
-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.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.net.URI;
-
-/** Page where you choose the application name, activity name, and optional test project info */
-public class ApplicationInfoPage extends WizardPage implements SelectionListener, ModifyListener,
- ITargetChangeListener {
- private static final String JDK_15 = "1.5"; //$NON-NLS-1$
- private final static String DUMMY_PACKAGE = "your.package.namespace";
-
- /** Suffix added by default to activity names */
- static final String ACTIVITY_NAME_SUFFIX = "Activity"; //$NON-NLS-1$
-
- private final NewProjectWizardState mValues;
-
- private Text mApplicationText;
- private Text mPackageText;
- private Text mActivityText;
- private Button mCreateActivityCheckbox;
- private Combo mSdkCombo;
-
- private boolean mIgnore;
- private Button mCreateTestCheckbox;
- private Text mTestProjectNameText;
- private Text mTestApplicationText;
- private Text mTestPackageText;
- private Label mTestProjectNameLabel;
- private Label mTestApplicationLabel;
- private Label mTestPackageLabel;
-
- /**
- * Create the wizard.
- */
- ApplicationInfoPage(NewProjectWizardState values) {
- super("appInfo"); //$NON-NLS-1$
- mValues = values;
-
- setTitle("Application Info");
- setDescription("Configure the new Android Project");
- AdtPlugin.getDefault().addTargetListener(this);
- }
-
- /**
- * Create contents of the wizard.
- */
- @Override
- @SuppressWarnings("unused") // Eclipse marks SWT constructors with side effects as unused
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
- container.setLayout(new GridLayout(2, false));
-
- Label applicationLabel = new Label(container, SWT.NONE);
- applicationLabel.setText("Application Name:");
-
- mApplicationText = new Text(container, SWT.BORDER);
- mApplicationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mApplicationText.addModifyListener(this);
-
- Label packageLabel = new Label(container, SWT.NONE);
- packageLabel.setText("Package Name:");
-
- mPackageText = new Text(container, SWT.BORDER);
- mPackageText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mPackageText.addModifyListener(this);
-
- if (mValues.mode != Mode.TEST) {
- mCreateActivityCheckbox = new Button(container, SWT.CHECK);
- mCreateActivityCheckbox.setText("Create Activity:");
- mCreateActivityCheckbox.addSelectionListener(this);
-
- mActivityText = new Text(container, SWT.BORDER);
- mActivityText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mActivityText.addModifyListener(this);
- }
-
- Label minSdkLabel = new Label(container, SWT.NONE);
- minSdkLabel.setText("Minimum SDK:");
-
- mSdkCombo = new Combo(container, SWT.NONE);
- GridData gdSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
- gdSdkCombo.widthHint = 200;
- mSdkCombo.setLayoutData(gdSdkCombo);
- mSdkCombo.addSelectionListener(this);
- mSdkCombo.addModifyListener(this);
-
- onSdkLoaded();
-
- setControl(container);
- new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
-
- mCreateTestCheckbox = new Button(container, SWT.CHECK);
- mCreateTestCheckbox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
- mCreateTestCheckbox.setText("Create a Test Project");
- mCreateTestCheckbox.addSelectionListener(this);
-
- mTestProjectNameLabel = new Label(container, SWT.NONE);
- mTestProjectNameLabel.setText("Test Project Name:");
-
- mTestProjectNameText = new Text(container, SWT.BORDER);
- mTestProjectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mTestProjectNameText.addModifyListener(this);
-
- mTestApplicationLabel = new Label(container, SWT.NONE);
- mTestApplicationLabel.setText("Test Application:");
-
- mTestApplicationText = new Text(container, SWT.BORDER);
- mTestApplicationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mTestApplicationText.addModifyListener(this);
-
- mTestPackageLabel = new Label(container, SWT.NONE);
- mTestPackageLabel.setText("Test Package:");
-
- mTestPackageText = new Text(container, SWT.BORDER);
- mTestPackageText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mTestPackageText.addModifyListener(this);
- }
-
- /** Controls whether the options for creating a paired test project should be shown */
- private void showTestOptions(boolean visible) {
- if (mValues.mode == Mode.SAMPLE) {
- visible = false;
- }
-
- mCreateTestCheckbox.setVisible(visible);
- mTestProjectNameLabel.setVisible(visible);
- mTestProjectNameText.setVisible(visible);
- mTestApplicationLabel.setVisible(visible);
- mTestApplicationText.setVisible(visible);
- mTestPackageLabel.setVisible(visible);
- mTestPackageText.setVisible(visible);
- }
-
- /** Controls whether the options for creating a paired test project should be enabled */
- private void enableTestOptions(boolean enabled) {
- mTestProjectNameLabel.setEnabled(enabled);
- mTestProjectNameText.setEnabled(enabled);
- mTestApplicationLabel.setEnabled(enabled);
- mTestApplicationText.setEnabled(enabled);
- mTestPackageLabel.setEnabled(enabled);
- mTestPackageText.setEnabled(enabled);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
-
- if (visible) {
- try {
- mIgnore = true;
- if (mValues.applicationName != null) {
- mApplicationText.setText(mValues.applicationName);
- }
- if (mValues.packageName != null) {
- mPackageText.setText(mValues.packageName);
- } else {
- mPackageText.setText(DUMMY_PACKAGE);
- }
-
- if (mValues.mode != Mode.TEST) {
- mCreateActivityCheckbox.setSelection(mValues.createActivity);
- mActivityText.setEnabled(mValues.createActivity);
- if (mValues.activityName != null) {
- mActivityText.setText(mValues.activityName);
- }
- }
- if (mValues.minSdk != null && mValues.minSdk.length() > 0) {
- mSdkCombo.setText(mValues.minSdk);
- }
-
- showTestOptions(mValues.mode == Mode.ANY);
- enableTestOptions(mCreateTestCheckbox.getSelection());
-
- if (mValues.testProjectName != null) {
- mTestProjectNameText.setText(mValues.testProjectName);
- }
- if (mValues.testApplicationName != null) {
- mTestApplicationText.setText(mValues.testApplicationName);
- }
- if (mValues.testProjectName != null) {
- mTestPackageText.setText(mValues.testProjectName);
- }
- } finally {
- mIgnore = false;
- }
- }
-
- // Start focus with the package name, since the other fields are typically assigned
- // reasonable defaults
- mPackageText.setFocus();
- mPackageText.selectAll();
-
- validatePage();
- }
-
- protected void setSdkTargets(IAndroidTarget[] targets, IAndroidTarget target) {
- if (targets == null) {
- targets = new IAndroidTarget[0];
- }
- int selectionIndex = -1;
- String[] items = new String[targets.length];
- for (int i = 0, n = targets.length; i < n; i++) {
- items[i] = targetLabel(targets[i]);
- if (targets[i] == target) {
- selectionIndex = i;
- }
- }
- try {
- mIgnore = true;
- mSdkCombo.setItems(items);
- mSdkCombo.setData(targets);
- if (selectionIndex != -1) {
- mSdkCombo.select(selectionIndex);
- }
- } finally {
- mIgnore = false;
- }
- }
-
- private String targetLabel(IAndroidTarget target) {
- // In the minimum SDK chooser, show the targets with api number and description,
- // such as "11 (Android 3.0)"
- return String.format("%1$s (%2$s)", target.getVersion().getApiString(),
- target.getFullName());
- }
-
- @Override
- public void dispose() {
- AdtPlugin.getDefault().removeTargetListener(this);
- super.dispose();
- }
-
- @Override
- public boolean isPageComplete() {
- // This page is only needed when creating new projects
- if (mValues.useExisting || mValues.mode != Mode.ANY) {
- return true;
- }
-
- // Ensure that we reach this page
- if (mValues.packageName == null) {
- return false;
- }
-
- return super.isPageComplete();
- }
-
- @Override
- public void modifyText(ModifyEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
- if (source == mSdkCombo) {
- mValues.minSdk = mSdkCombo.getText().trim();
- IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
- // An editable combo will treat item selection the same way as a user edit,
- // so we need to see if the string looks like a labeled version
- int index = mSdkCombo.getSelectionIndex();
- if (index != -1) {
- if (index >= 0 && index < targets.length) {
- IAndroidTarget target = targets[index];
- if (targetLabel(target).equals(mValues.minSdk)) {
- mValues.minSdk = target.getVersion().getApiString();
- }
- }
- }
-
- // Ensure that we never pick up the (Android x.y) suffix shown in combobox
- // for readability
- int separator = mValues.minSdk.indexOf(' ');
- if (separator != -1) {
- mValues.minSdk = mValues.minSdk.substring(0, separator);
- }
- mValues.minSdkModifiedByUser = true;
- mValues.updateSdkTargetToMatchMinSdkVersion();
- } else if (source == mApplicationText) {
- mValues.applicationName = mApplicationText.getText().trim();
- mValues.applicationNameModifiedByUser = true;
-
- if (!mValues.testApplicationNameModified) {
- mValues.testApplicationName = suggestTestApplicationName(mValues.applicationName);
- try {
- mIgnore = true;
- mTestApplicationText.setText(mValues.testApplicationName);
- } finally {
- mIgnore = false;
- }
- }
-
- } else if (source == mPackageText) {
- mValues.packageName = mPackageText.getText().trim();
- mValues.packageNameModifiedByUser = true;
-
- if (!mValues.testPackageModified) {
- mValues.testPackageName = suggestTestPackage(mValues.packageName);
- try {
- mIgnore = true;
- mTestPackageText.setText(mValues.testPackageName);
- } finally {
- mIgnore = false;
- }
- }
- } else if (source == mActivityText) {
- mValues.activityName = mActivityText.getText().trim();
- mValues.activityNameModifiedByUser = true;
- } else if (source == mTestApplicationText) {
- mValues.testApplicationName = mTestApplicationText.getText().trim();
- mValues.testApplicationNameModified = true;
- } else if (source == mTestPackageText) {
- mValues.testPackageName = mTestPackageText.getText().trim();
- mValues.testPackageModified = true;
- } else if (source == mTestProjectNameText) {
- mValues.testProjectName = mTestProjectNameText.getText().trim();
- mValues.testProjectModified = true;
- }
-
- validatePage();
- }
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
-
- if (source == mCreateActivityCheckbox) {
- mValues.createActivity = mCreateActivityCheckbox.getSelection();
- mActivityText.setEnabled(mValues.createActivity);
- } else if (source == mSdkCombo) {
- int index = mSdkCombo.getSelectionIndex();
- IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
- if (index != -1) {
- if (index >= 0 && index < targets.length) {
- IAndroidTarget target = targets[index];
- // Even though we are showing the logical version name, we place the
- // actual api number as the minimum SDK
- mValues.minSdk = target.getVersion().getApiString();
- }
- } else {
- String text = mSdkCombo.getText();
- boolean found = false;
- for (IAndroidTarget target : targets) {
- if (targetLabel(target).equals(text)) {
- mValues.minSdk = target.getVersion().getApiString();
- found = true;
- break;
- }
- }
- if (!found) {
- mValues.minSdk = text;
- }
- }
- } else if (source == mCreateTestCheckbox) {
- mValues.createPairProject = mCreateTestCheckbox.getSelection();
- enableTestOptions(mValues.createPairProject);
- if (mValues.createPairProject) {
- if (mValues.testProjectName == null || mValues.testProjectName.length() == 0) {
- mValues.testProjectName = suggestTestProjectName(mValues.projectName);
- }
- if (mValues.testApplicationName == null ||
- mValues.testApplicationName.length() == 0) {
- mValues.testApplicationName =
- suggestTestApplicationName(mValues.applicationName);
- }
- if (mValues.testPackageName == null || mValues.testPackageName.length() == 0) {
- mValues.testPackageName = suggestTestPackage(mValues.packageName);
- }
-
- try {
- mIgnore = true;
- mTestProjectNameText.setText(mValues.testProjectName);
- mTestApplicationText.setText(mValues.testApplicationName);
- mTestPackageText.setText(mValues.testPackageName);
- } finally {
- mIgnore = false;
- }
- }
- }
-
- validatePage();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- private void validatePage() {
- IStatus status = validatePackage(mValues.packageName);
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validActivity = validateActivity();
- if (validActivity != null) {
- status = validActivity;
- }
- }
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validMinSdk = validateMinSdk();
- if (validMinSdk != null) {
- status = validMinSdk;
- }
- }
-
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validSourceFolder = validateSourceFolder();
- if (validSourceFolder != null) {
- status = validSourceFolder;
- }
- }
-
- // If creating a test project to go along with the main project, also validate
- // the additional test project parameters
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- if (mValues.createPairProject) {
- IStatus validTestProject = ProjectNamePage.validateProjectName(
- mValues.testProjectName);
- if (validTestProject != null) {
- status = validTestProject;
- }
-
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validTestLocation = validateTestProjectLocation();
- if (validTestLocation != null) {
- status = validTestLocation;
- }
- }
-
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validTestPackage = validatePackage(mValues.testPackageName);
- if (validTestPackage != null) {
- status = new Status(validTestPackage.getSeverity(),
- AdtPlugin.PLUGIN_ID,
- validTestPackage.getMessage() + " (in test package)");
- }
- }
-
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- if (mValues.projectName.equals(mValues.testProjectName)) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "The main project name and the test project name must be different.");
- }
- }
- }
- }
-
- // -- update UI & enable finish if there's no error
- 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 validateTestProjectLocation() {
- assert mValues.createPairProject;
-
- // Validate location
- Path path = new Path(mValues.projectLocation.getPath());
- if (!mValues.useExisting) {
- if (!mValues.useDefaultLocation) {
- // If not using the default value validate the location.
- URI uri = URIUtil.toURI(path.toOSString());
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IProject handle = workspace.getRoot().getProject(mValues.testProjectName);
- IStatus locationStatus = workspace.validateProjectLocationURI(handle, uri);
- if (!locationStatus.isOK()) {
- return locationStatus;
- }
- // The location is valid as far as Eclipse is concerned (i.e. mostly not
- // an existing workspace project.) Check it either doesn't exist or is
- // a directory that is empty.
- File f = path.toFile();
- if (f.exists() && !f.isDirectory()) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "A directory name must be specified.");
- } else if (f.isDirectory()) {
- // However if the directory exists, we should put a
- // warning if it is not empty. We don't put an error
- // (we'll ask the user again for confirmation before
- // using the directory.)
- String[] l = f.list();
- if (l != null && l.length != 0) {
- return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
- "The selected output directory is not empty.");
- }
- }
- } else {
- IPath destPath = path.removeLastSegments(1).append(mValues.testProjectName);
- File dest = destPath.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.",
- mValues.testProjectName));
- }
- }
- }
-
- return null;
- }
-
- private IStatus validateSourceFolder() {
- // This check does nothing when creating a new project.
- // This check is also useless when no activity is present or created.
- mValues.sourceFolder = SdkConstants.FD_SOURCES;
- if (!mValues.useExisting || !mValues.createActivity) {
- return null;
- }
-
- String osTarget = mValues.activityName;
- if (osTarget.indexOf('.') == -1) {
- osTarget = mValues.packageName + File.separator + osTarget;
- } else if (osTarget.indexOf('.') == 0) {
- osTarget = mValues.packageName + osTarget;
- }
- osTarget = osTarget.replace('.', File.separatorChar) + SdkConstants.DOT_JAVA;
-
- File projectDir = mValues.projectLocation;
- File[] allDirs = projectDir.listFiles(new FileFilter() {
- @Override
- public boolean accept(File pathname) {
- return pathname.isDirectory();
- }
- });
- if (allDirs != null) {
- boolean found = false;
- for (File f : allDirs) {
- Path path = new Path(f.getAbsolutePath());
- File java_activity = path.append(osTarget).toFile();
- if (java_activity.isFile()) {
- mValues.sourceFolder = f.getName();
- found = true;
- break;
- }
- }
-
- if (!found) {
- String projectPath = projectDir.getPath();
- if (allDirs.length > 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("%1$s can not be found under %2$s.", osTarget,
- projectPath));
- } else {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("No source folders can be found in %1$s.",
- projectPath));
- }
- }
- }
-
- return null;
- }
-
- private IStatus validateMinSdk() {
- // Validate min SDK field
- // If the min sdk version is empty, it is always accepted.
- if (mValues.minSdk == null || mValues.minSdk.length() == 0) {
- return null;
- }
-
- IAndroidTarget target = mValues.target;
- if (target == null) {
- return null;
- }
-
- // If the current target is a preview, explicitly indicate minSdkVersion
- // must be set to this target name.
- if (target.getVersion().isPreview() && !target.getVersion().equals(mValues.minSdk)) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format(
- "The SDK target is a preview. Min SDK Version must be set to '%s'.",
- target.getVersion().getCodename()));
- }
-
- if (!target.getVersion().equals(mValues.minSdk)) {
- return new Status(target.getVersion().isPreview() ? IStatus.ERROR : IStatus.WARNING,
- AdtPlugin.PLUGIN_ID,
- "The API level for the selected SDK target does not match the Min SDK Version."
- );
- }
-
- return null;
- }
-
- public static IStatus validatePackage(String packageFieldContents) {
- // Validate package
- if (packageFieldContents == null || packageFieldContents.length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Package name must be specified.");
- } else if (packageFieldContents.equals(DUMMY_PACKAGE)) {
- // The dummy package name is just a placeholder package (which isn't even valid
- // because it contains the reserved Java keyword "package") but we want to
- // make the error message say that a proper package should be entered rather than
- // what's wrong with this specific package. (And the reason we provide a dummy
- // package rather than a blank line is to make it more clear to beginners what
- // we're looking for.
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Package name must be specified.");
- }
- // Check it's a valid package string
- IStatus status = JavaConventions.validatePackageName(packageFieldContents, JDK_15,
- JDK_15);
- if (!status.isOK()) {
- return status;
- }
-
- // The Android Activity Manager does not accept packages names with only one
- // identifier. Check the package name has at least one dot in them (the previous rule
- // validated that if such a dot exist, it's not the first nor last characters of the
- // string.)
- if (packageFieldContents.indexOf('.') == -1) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Package name must have at least two identifiers.");
- }
-
- return null;
- }
-
- public static IStatus validateClass(String className) {
- if (className == null || className.length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Class name must be specified.");
- }
- if (className.indexOf('.') != -1) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Enter just a class name, not a full package name");
- }
- return JavaConventions.validateJavaTypeName(className, JDK_15, JDK_15);
- }
-
- private IStatus validateActivity() {
- // Validate activity (if creating an activity)
- if (!mValues.createActivity) {
- return null;
- }
-
- return validateActivity(mValues.activityName);
- }
-
- /**
- * Validates the given activity name
- *
- * @param activityFieldContents the activity name to validate
- * @return a status for whether the activity name is valid
- */
- public static IStatus validateActivity(String activityFieldContents) {
- // Validate activity field
- if (activityFieldContents == null || activityFieldContents.length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Activity name must be specified.");
- } else if (ACTIVITY_NAME_SUFFIX.equals(activityFieldContents)) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "Enter a valid activity name");
- } else if (activityFieldContents.contains("..")) { //$NON-NLS-1$
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Package segments in activity name cannot be empty (..)");
- }
- // The activity field can actually contain part of a sub-package name
- // or it can start with a dot "." to indicates it comes from the parent package
- // name.
- String packageName = ""; //$NON-NLS-1$
- int pos = activityFieldContents.lastIndexOf('.');
- if (pos >= 0) {
- packageName = activityFieldContents.substring(0, pos);
- if (packageName.startsWith(".")) { //$NON-NLS-1$
- packageName = packageName.substring(1);
- }
-
- activityFieldContents = activityFieldContents.substring(pos + 1);
- }
-
- // the activity field can contain a simple java identifier, or a
- // package name or one that starts with a dot. So if it starts with a dot,
- // ignore this dot -- the rest must look like a package name.
- if (activityFieldContents.length() > 0 && activityFieldContents.charAt(0) == '.') {
- activityFieldContents = activityFieldContents.substring(1);
- }
-
- // Check it's a valid activity string
- IStatus status = JavaConventions.validateTypeVariableName(activityFieldContents, JDK_15,
- JDK_15);
- if (!status.isOK()) {
- return status;
- }
-
- // Check it's a valid package string
- if (packageName.length() > 0) {
- status = JavaConventions.validatePackageName(packageName, JDK_15, JDK_15);
- if (!status.isOK()) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- status.getMessage() + " (in the activity name)");
- }
- }
-
- return null;
- }
-
- // ---- Implement ITargetChangeListener ----
-
- @Override
- public void onSdkLoaded() {
- if (mSdkCombo == null) {
- return;
- }
-
- // Update the sdk target selector with the new targets
-
- // get the targets from the sdk
- IAndroidTarget[] targets = null;
- if (Sdk.getCurrent() != null) {
- targets = Sdk.getCurrent().getTargets();
- }
- setSdkTargets(targets, mValues.target);
- }
-
- @Override
- public void onProjectTargetChange(IProject changedProject) {
- // Ignore
- }
-
- @Override
- public void onTargetLoaded(IAndroidTarget target) {
- // Ignore
- }
-
- public static String suggestTestApplicationName(String applicationName) {
- if (applicationName == null) {
- applicationName = ""; //$NON-NLS-1$
- }
- if (applicationName.indexOf(' ') != -1) {
- return applicationName + " Test"; //$NON-NLS-1$
- } else {
- return applicationName + "Test"; //$NON-NLS-1$
- }
- }
-
- public static String suggestTestProjectName(String projectName) {
- if (projectName == null) {
- projectName = ""; //$NON-NLS-1$
- }
- if (projectName.length() > 0 && Character.isUpperCase(projectName.charAt(0))) {
- return projectName + "Test"; //$NON-NLS-1$
- } else {
- return projectName + "-test"; //$NON-NLS-1$
- }
- }
-
-
- public static String suggestTestPackage(String packagePath) {
- if (packagePath == null) {
- packagePath = ""; //$NON-NLS-1$
- }
- return packagePath + ".test"; //$NON-NLS-1$
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/FileStoreAdapter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/FileStoreAdapter.java
deleted file mode 100755
index 0f4e87e9f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/FileStoreAdapter.java
+++ /dev/null
@@ -1,160 +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.newproject;
-
-import org.eclipse.core.filesystem.IFileInfo;
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.filesystem.IFileSystem;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-
-/**
- * IFileStore implementation that delegates to the give {@link IFileStore}.
- * This makes it easier to just override a single method from a store.
- */
-class FileStoreAdapter implements IFileStore {
-
- private final IFileStore mStore;
-
- public FileStoreAdapter(IFileStore store) {
- mStore = store;
- }
-
- @SuppressWarnings("rawtypes")
- @Override
- public Object getAdapter(Class adapter) {
- return mStore.getAdapter(adapter);
- }
-
- @Override
- public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
- return mStore.childInfos(options, monitor);
- }
-
- @Override
- public String[] childNames(int options, IProgressMonitor monitor)
- throws CoreException {
- return mStore.childNames(options, monitor);
- }
-
- @Override
- public IFileStore[] childStores(int options, IProgressMonitor monitor) throws CoreException {
- return mStore.childStores(options, monitor);
- }
-
- @Override
- public void copy(IFileStore destination, int options, IProgressMonitor monitor)
- throws CoreException {
- mStore.copy(destination, options, monitor);
- }
-
- @Override
- public void delete(int options, IProgressMonitor monitor) throws CoreException {
- mStore.delete(options, monitor);
- }
-
- @Override
- public IFileInfo fetchInfo() {
- return mStore.fetchInfo();
- }
-
- @Override
- public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
- return mStore.fetchInfo(options, monitor);
- }
-
- @Deprecated
- @Override
- public IFileStore getChild(IPath path) {
- return mStore.getChild(path);
- }
-
- @Override
- public IFileStore getFileStore(IPath path) {
- return mStore.getFileStore(path);
- }
-
- @Override
- public IFileStore getChild(String name) {
- return mStore.getChild(name);
- }
-
- @Override
- public IFileSystem getFileSystem() {
- return mStore.getFileSystem();
- }
-
- @Override
- public String getName() {
- return mStore.getName();
- }
-
- @Override
- public IFileStore getParent() {
- return mStore.getParent();
- }
-
- @Override
- public boolean isParentOf(IFileStore other) {
- return mStore.isParentOf(other);
- }
-
- @Override
- public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
- return mStore.mkdir(options, monitor);
- }
-
- @Override
- public void move(IFileStore destination, int options, IProgressMonitor monitor)
- throws CoreException {
- mStore.move(destination, options, monitor);
- }
-
- @Override
- public InputStream openInputStream(int options, IProgressMonitor monitor)
- throws CoreException {
- return mStore.openInputStream(options, monitor);
- }
-
- @Override
- public OutputStream openOutputStream(int options, IProgressMonitor monitor)
- throws CoreException {
- return mStore.openOutputStream(options, monitor);
- }
-
- @Override
- public void putInfo(IFileInfo info, int options, IProgressMonitor monitor)
- throws CoreException {
- mStore.putInfo(info, options, monitor);
- }
-
- @Override
- public File toLocalFile(int options, IProgressMonitor monitor) throws CoreException {
- return mStore.toLocalFile(options, monitor);
- }
-
- @Override
- public URI toURI() {
- return mStore.toURI();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java
deleted file mode 100644
index 1e02fedae..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java
+++ /dev/null
@@ -1,512 +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.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.tools.lint.detector.api.LintUtils;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.CellLabelProvider;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.ICheckStateListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TextCellEditor;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Rectangle;
-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.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkingSet;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** WizardPage for importing Android projects */
-class ImportPage extends WizardPage implements SelectionListener, IStructuredContentProvider,
- ICheckStateListener, KeyListener, TraverseListener, ControlListener {
- private static final int DIR_COLUMN = 0;
- private static final int NAME_COLUMN = 1;
-
- private final NewProjectWizardState mValues;
- private List<ImportedProject> mProjectPaths;
- private final IProject[] mExistingProjects;
-
- private Text mDir;
- private Button mBrowseButton;
- private Button mCopyCheckBox;
- private Button mRefreshButton;
- private Button mDeselectAllButton;
- private Button mSelectAllButton;
- private Table mTable;
- private CheckboxTableViewer mCheckboxTableViewer;
- private WorkingSetGroup mWorkingSetGroup;
-
- ImportPage(NewProjectWizardState values) {
- super("importPage"); //$NON-NLS-1$
- mValues = values;
- setTitle("Import Projects");
- setDescription("Select a directory to search for existing Android projects");
- mWorkingSetGroup = new WorkingSetGroup();
- setWorkingSets(new IWorkingSet[0]);
-
- // Record all projects such that we can ensure that the project names are unique
- IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
- mExistingProjects = workspaceRoot.getProjects();
- }
-
- public void init(IStructuredSelection selection, IWorkbenchPart activePart) {
- setWorkingSets(WorkingSetHelper.getSelectedWorkingSet(selection, activePart));
- }
-
- @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 directoryLabel = new Label(container, SWT.NONE);
- directoryLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- directoryLabel.setText("Root Directory:");
-
- mDir = new Text(container, SWT.BORDER);
- mDir.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mDir.addKeyListener(this);
- mDir.addTraverseListener(this);
-
- mBrowseButton = new Button(container, SWT.NONE);
- mBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- mBrowseButton.setText("Browse...");
- mBrowseButton.addSelectionListener(this);
-
- Label projectsLabel = new Label(container, SWT.NONE);
- projectsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
- projectsLabel.setText("Projects:");
-
- mTable = new Table(container, SWT.CHECK);
- mTable.setHeaderVisible(true);
- mCheckboxTableViewer = new CheckboxTableViewer(mTable);
-
- TableViewerColumn dirViewerColumn = new TableViewerColumn(mCheckboxTableViewer, SWT.NONE);
- TableColumn dirColumn = dirViewerColumn.getColumn();
- dirColumn.setWidth(200);
- dirColumn.setText("Project to Import");
- TableViewerColumn nameViewerColumn = new TableViewerColumn(mCheckboxTableViewer, SWT.NONE);
- TableColumn nameColumn = nameViewerColumn.getColumn();
- nameColumn.setWidth(200);
- nameColumn.setText("New Project Name");
- nameViewerColumn.setEditingSupport(new ProjectNameEditingSupport(mCheckboxTableViewer));
-
- mTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 4));
- mTable.setLinesVisible(true);
- mTable.setHeaderVisible(true);
- mTable.addSelectionListener(this);
- mTable.addControlListener(this);
- mCheckboxTableViewer.setContentProvider(this);
- mCheckboxTableViewer.setInput(this);
- mCheckboxTableViewer.addCheckStateListener(this);
- mCheckboxTableViewer.setLabelProvider(new ProjectCellLabelProvider());
-
- mSelectAllButton = new Button(container, SWT.NONE);
- mSelectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- mSelectAllButton.setText("Select All");
- mSelectAllButton.addSelectionListener(this);
-
- mDeselectAllButton = new Button(container, SWT.NONE);
- mDeselectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- mDeselectAllButton.setText("Deselect All");
- mDeselectAllButton.addSelectionListener(this);
-
- mRefreshButton = new Button(container, SWT.NONE);
- mRefreshButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- mRefreshButton.setText("Refresh");
- mRefreshButton.addSelectionListener(this);
- new Label(container, SWT.NONE);
-
- mCopyCheckBox = new Button(container, SWT.CHECK);
- mCopyCheckBox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
- mCopyCheckBox.setText("Copy projects into workspace");
- mCopyCheckBox.addSelectionListener(this);
-
- Composite group = mWorkingSetGroup.createControl(container);
- group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
-
- updateColumnWidths();
- }
-
- private void updateColumnWidths() {
- Rectangle r = mTable.getClientArea();
- int availableWidth = r.width;
- // Add all available size to the first column
- for (int i = 1; i < mTable.getColumnCount(); i++) {
- TableColumn column = mTable.getColumn(i);
- availableWidth -= column.getWidth();
- }
- if (availableWidth > 100) {
- mTable.getColumn(0).setWidth(availableWidth);
- }
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- validatePage();
- }
-
- private void refresh() {
- File root = new File(mDir.getText().trim());
- mProjectPaths = searchForProjects(root);
- mCheckboxTableViewer.refresh();
- mCheckboxTableViewer.setAllChecked(true);
-
- updateValidity();
- validatePage();
- }
-
- private void updateValidity(){
- List<ImportedProject> selected = new ArrayList<ImportedProject>();
- List<ImportedProject> disabled = new ArrayList<ImportedProject>();
- for (ImportedProject project : mProjectPaths) {
- String projectName = project.getProjectName();
- boolean invalid = false;
- for (IProject existingProject : mExistingProjects) {
- if (projectName.equals(existingProject.getName())) {
- invalid = true;
- break;
- }
- }
- if (invalid) {
- disabled.add(project);
- } else {
- selected.add(project);
- }
- }
-
- mValues.importProjects = selected;
-
- mCheckboxTableViewer.setGrayedElements(disabled.toArray());
- mCheckboxTableViewer.setCheckedElements(selected.toArray());
- mCheckboxTableViewer.refresh();
- mCheckboxTableViewer.getTable().setFocus();
- }
-
- private List<ImportedProject> searchForProjects(File dir) {
- List<ImportedProject> projects = new ArrayList<ImportedProject>();
- addProjects(dir, projects, dir.getPath().length() + 1);
- return projects;
- }
-
- /** Finds all project directories under the given directory */
- private void addProjects(File dir, List<ImportedProject> projects, int prefixLength) {
- if (dir.isDirectory()) {
- if (LintUtils.isManifestFolder(dir)) {
- String relative = dir.getPath();
- if (relative.length() > prefixLength) {
- relative = relative.substring(prefixLength);
- }
- projects.add(new ImportedProject(dir, relative));
- }
-
- File[] children = dir.listFiles();
- if (children != null) {
- for (File child : children) {
- addProjects(child, projects, prefixLength);
- }
- }
- }
- }
-
- private void validatePage() {
- IStatus status = null;
-
- // Validate project name -- unless we're creating a sample, in which case
- // the user will get a chance to pick the name on the Sample page
- if (mProjectPaths == null || mProjectPaths.isEmpty()) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Select a directory to search for existing Android projects");
- } else if (mValues.importProjects == null || mValues.importProjects.isEmpty()) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Select at least one project");
- } else {
- for (ImportedProject project : mValues.importProjects) {
- if (mCheckboxTableViewer.getGrayed(project)) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("Cannot import %1$s because the project name is in use",
- project.getProjectName()));
- break;
- } else {
- status = ProjectNamePage.validateProjectName(project.getProjectName());
- if (status != null && !status.isOK()) {
- // Need to insert project name to make it clear which project name
- // is in violation
- if (mValues.importProjects.size() > 1) {
- String message = String.format("%1$s: %2$s",
- project.getProjectName(), status.getMessage());
- status = new Status(status.getSeverity(), AdtPlugin.PLUGIN_ID,
- message);
- }
- break;
- } else {
- status = null; // Don't leave non null status with isOK() == true
- }
- }
- }
- }
-
- // -- update UI & enable finish if there's no error
- 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);
- }
- }
-
- /**
- * 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 SelectionListener ----
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- Object source = e.getSource();
- if (source == mBrowseButton) {
- // Choose directory
- DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.OPEN);
- String path = mDir.getText().trim();
- if (path.length() > 0) {
- dialog.setFilterPath(path);
- }
- String file = dialog.open();
- if (file != null) {
- mDir.setText(file);
- refresh();
- }
- } else if (source == mSelectAllButton) {
- mCheckboxTableViewer.setAllChecked(true);
- mValues.importProjects = mProjectPaths;
- } else if (source == mDeselectAllButton) {
- mCheckboxTableViewer.setAllChecked(false);
- mValues.importProjects = Collections.emptyList();
- } else if (source == mRefreshButton || source == mDir) {
- refresh();
- } else if (source == mCopyCheckBox) {
- mValues.copyIntoWorkspace = mCopyCheckBox.getSelection();
- }
-
- validatePage();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- // ---- KeyListener ----
-
- @Override
- public void keyPressed(KeyEvent e) {
- if (e.getSource() == mDir) {
- if (e.keyCode == SWT.CR) {
- refresh();
- }
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- // ---- TraverseListener ----
-
- @Override
- public void keyTraversed(TraverseEvent e) {
- // Prevent Return from running through the wizard; return is handled by
- // key listener to refresh project list instead
- if (SWT.TRAVERSE_RETURN == e.detail) {
- e.doit = false;
- }
- }
-
- // ---- Implements IStructuredContentProvider ----
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return mProjectPaths != null ? mProjectPaths.toArray() : new Object[0];
- }
-
- // ---- Implements ICheckStateListener ----
-
- @Override
- public void checkStateChanged(CheckStateChangedEvent event) {
- // Try to disable other elements that conflict with this
- Object[] checked = mCheckboxTableViewer.getCheckedElements();
- List<ImportedProject> selected = new ArrayList<ImportedProject>(checked.length);
- for (Object o : checked) {
- if (!mCheckboxTableViewer.getGrayed(o)) {
- selected.add((ImportedProject) o);
- }
- }
- mValues.importProjects = selected;
- validatePage();
-
- mCheckboxTableViewer.update(event.getElement(), null);
- }
-
- // ---- Implements ControlListener ----
-
- @Override
- public void controlMoved(ControlEvent e) {
- }
-
- @Override
- public void controlResized(ControlEvent e) {
- updateColumnWidths();
- }
-
- private final class ProjectCellLabelProvider extends CellLabelProvider {
- @Override
- public void update(ViewerCell cell) {
- Object element = cell.getElement();
- int index = cell.getColumnIndex();
- ImportedProject project = (ImportedProject) element;
-
- Display display = mTable.getDisplay();
- Color fg;
- if (mCheckboxTableViewer.getGrayed(element)) {
- fg = display.getSystemColor(SWT.COLOR_DARK_GRAY);
- } else {
- fg = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
- }
- cell.setForeground(fg);
- cell.setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
-
- switch (index) {
- case DIR_COLUMN: {
- // Directory name
- cell.setText(project.getRelativePath());
- return;
- }
-
- case NAME_COLUMN: {
- // New name
- cell.setText(project.getProjectName());
- return;
- }
- default:
- assert false : index;
- }
- cell.setText("");
- }
- }
-
- /** Editing support for the project name column */
- private class ProjectNameEditingSupport extends EditingSupport {
- private ProjectNameEditingSupport(ColumnViewer viewer) {
- super(viewer);
- }
-
- @Override
- protected void setValue(Object element, Object value) {
- ImportedProject project = (ImportedProject) element;
- project.setProjectName(value.toString());
- mCheckboxTableViewer.update(element, null);
- updateValidity();
- validatePage();
- }
-
- @Override
- protected Object getValue(Object element) {
- ImportedProject project = (ImportedProject) element;
- return project.getProjectName();
- }
-
- @Override
- protected CellEditor getCellEditor(Object element) {
- return new TextCellEditor(mTable);
- }
-
- @Override
- protected boolean canEdit(Object element) {
- return true;
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportProjectWizard.java
deleted file mode 100644
index 1004fd692..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportProjectWizard.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.newproject;
-
-import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
-import static com.android.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-
-import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-
-import java.io.File;
-
-
-/**
- * An "Import Android Project" wizard.
- */
-public class ImportProjectWizard extends Wizard implements INewWizard {
- private static final String PROJECT_LOGO_LARGE = "icons/android-64.png"; //$NON-NLS-1$
-
- private NewProjectWizardState mValues;
- private ImportPage mImportPage;
- private IStructuredSelection mSelection;
-
- /** Constructs a new wizard default project wizard */
- public ImportProjectWizard() {
- }
-
- @Override
- public void addPages() {
- mValues = new NewProjectWizardState(Mode.ANY);
- mImportPage = new ImportPage(mValues);
- if (mSelection != null) {
- mImportPage.init(mSelection, AdtUtils.getActivePart());
- }
- addPage(mImportPage);
- }
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- mSelection = selection;
-
- setHelpAvailable(false); // TODO have help
- ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
- setDefaultPageImageDescriptor(desc);
-
- // Trigger a check to see if the SDK needs to be reloaded (which will
- // invoke onSdkLoaded asynchronously as needed).
- AdtPlugin.getDefault().refreshSdk();
- }
-
- @Override
- public boolean performFinish() {
- File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER + File.separator
- + FN_PROJECT_PROGUARD_FILE);
- if (!file.exists()) {
- AdtPlugin.displayError("Tools Out of Date?",
- String.format("It looks like you do not have the latest version of the "
- + "SDK Tools installed. Make sure you update via the SDK Manager "
- + "first. (Could not find %1$s)", file.getPath()));
- return false;
- }
-
- NewProjectCreator creator = new NewProjectCreator(mValues, getContainer());
- if (!(creator.createAndroidProjects())) {
- return false;
- }
-
- // Open the default Java Perspective
- OpenJavaPerspectiveAction action = new OpenJavaPerspectiveAction();
- action.run();
- return true;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportedProject.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportedProject.java
deleted file mode 100644
index 74af651ca..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportedProject.java
+++ /dev/null
@@ -1,256 +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.newproject;
-
-import static com.android.SdkConstants.ATTR_NAME;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.xml.AndroidManifestParser;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.common.xml.ManifestData.Activity;
-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.sdk.Sdk;
-import com.android.io.FolderWrapper;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
-
-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.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** An Android project to be imported */
-class ImportedProject {
- private final File mLocation;
- private String mActivityName;
- private ManifestData mManifest;
- private String mProjectName;
- private String mRelativePath;
-
- ImportedProject(File location, String relativePath) {
- super();
- mLocation = location;
- mRelativePath = relativePath;
- }
-
- File getLocation() {
- return mLocation;
- }
-
- String getRelativePath() {
- return mRelativePath;
- }
-
- @Nullable
- ManifestData getManifest() {
- if (mManifest == null) {
- try {
- mManifest = AndroidManifestParser.parse(new FolderWrapper(mLocation));
- } catch (SAXException e) {
- // Some sort of error in the manifest file: report to the user in a better way?
- AdtPlugin.log(e, null);
- return null;
- } catch (Exception e) {
- AdtPlugin.log(e, null);
- return null;
- }
- }
-
- return mManifest;
- }
-
- @Nullable
- public String getActivityName() {
- if (mActivityName == null) {
- // Compute the project name and the package name from the manifest
- ManifestData manifest = getManifest();
- if (manifest != null) {
- if (manifest.getLauncherActivity() != null) {
- mActivityName = manifest.getLauncherActivity().getName();
- }
- if (mActivityName == null || mActivityName.isEmpty()) {
- Activity[] activities = manifest.getActivities();
- for (Activity activity : activities) {
- mActivityName = activity.getName();
- if (mActivityName != null && !mActivityName.isEmpty()) {
- break;
- }
- }
- }
- if (mActivityName != null) {
- int index = mActivityName.lastIndexOf('.');
- mActivityName = mActivityName.substring(index + 1);
- }
- }
- }
-
- return mActivityName;
- }
-
- @NonNull
- public String getProjectName() {
- if (mProjectName == null) {
- // Are we importing an Eclipse project? If so just use the existing project name
- mProjectName = findEclipseProjectName();
- if (mProjectName != null) {
- return mProjectName;
- }
-
- String activityName = getActivityName();
- if (activityName == null || activityName.isEmpty()) {
- // I could also look at the build files, say build.xml from ant, and
- // try to glean the project name from there
- mProjectName = mLocation.getName();
- } else {
- // Try to derive it from the activity name:
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IStatus nameStatus = workspace.validateName(activityName, IResource.PROJECT);
- if (nameStatus.isOK()) {
- mProjectName = activityName;
- } else {
- // Try to derive it by escaping characters
- StringBuilder sb = new StringBuilder();
- for (int i = 0, n = activityName.length(); i < n; i++) {
- char c = activityName.charAt(i);
- if (c != IPath.DEVICE_SEPARATOR && c != IPath.SEPARATOR && c != '\\') {
- sb.append(c);
- }
- }
- if (sb.length() == 0) {
- mProjectName = mLocation.getName();
- } else {
- mProjectName = sb.toString();
- }
- }
- }
- }
-
- return mProjectName;
- }
-
- @Nullable
- private String findEclipseProjectName() {
- File projectFile = new File(mLocation, ".project"); //$NON-NLS-1$
- if (projectFile.exists()) {
- String xml;
- try {
- xml = Files.toString(projectFile, Charsets.UTF_8);
- Document doc = DomUtilities.parseDocument(xml, false);
- if (doc != null) {
- NodeList names = doc.getElementsByTagName(ATTR_NAME);
- if (names.getLength() >= 1) {
- Node nameElement = names.item(0);
- String name = nameElement.getTextContent().trim();
- if (!name.isEmpty()) {
- return name;
- }
- }
- }
- } catch (IOException e) {
- // pass: don't attempt to read project name; must be some sort of unrelated
- // file with the same name, perhaps from a different editor or IDE
- }
- }
-
- return null;
- }
-
- public void setProjectName(@NonNull String newName) {
- mProjectName = newName;
- }
-
- public IAndroidTarget getTarget() {
- // Pick a target:
- // First try to find the one requested by project.properties
- IAndroidTarget[] targets = Sdk.getCurrent().getTargets();
- ProjectProperties properties = ProjectProperties.load(mLocation.getPath(),
- PropertyType.PROJECT);
- if (properties != null) {
- String targetProperty = properties.getProperty(ProjectProperties.PROPERTY_TARGET);
- if (targetProperty != null) {
- Matcher m = Pattern.compile("android-(.+)").matcher( //$NON-NLS-1$
- targetProperty.trim());
- if (m.matches()) {
- String targetName = m.group(1);
- int targetLevel;
- try {
- targetLevel = Integer.parseInt(targetName);
- } catch (NumberFormatException nufe) {
- // pass
- targetLevel = -1;
- }
- for (IAndroidTarget t : targets) {
- AndroidVersion version = t.getVersion();
- if (version.isPreview() && targetName.equals(version.getCodename())) {
- return t;
- } else if (targetLevel == version.getApiLevel()) {
- return t;
- }
- }
- if (targetLevel > 0) {
- // If not found, pick the closest one that is higher than the
- // api level
- IAndroidTarget target = targets[targets.length - 1];
- int targetDelta = target.getVersion().getApiLevel() - targetLevel;
- for (IAndroidTarget t : targets) {
- int newDelta = t.getVersion().getApiLevel() - targetLevel;
- if (newDelta >= 0 && newDelta < targetDelta) {
- targetDelta = newDelta;
- target = t;
- }
- }
-
- return target;
- }
- }
- }
- }
-
- // If not found, pick the closest one to the one requested by the
- // project (in project.properties) that is still >= the minSdk version
- IAndroidTarget target = targets[targets.length - 1];
- ManifestData manifest = getManifest();
- if (manifest != null) {
- int minSdkLevel = manifest.getMinSdkVersion();
- int targetDelta = target.getVersion().getApiLevel() - minSdkLevel;
- for (IAndroidTarget t : targets) {
- int newDelta = t.getVersion().getApiLevel() - minSdkLevel;
- if (newDelta >= 0 && newDelta < targetDelta) {
- targetDelta = newDelta;
- target = t;
- }
- }
- }
-
- return target;
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java
deleted file mode 100644
index d168c7503..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java
+++ /dev/null
@@ -1,1520 +0,0 @@
-/*
- * Copyright (C) 2007 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.newproject;
-
-import static com.android.SdkConstants.FN_PROJECT_PROPERTIES;
-import static com.android.sdklib.internal.project.ProjectProperties.PROPERTY_LIBRARY;
-
-import static org.eclipse.core.resources.IResource.DEPTH_ZERO;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.ide.common.res2.ValueXmlHelper;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.common.xml.XmlFormatStyle;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-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.preferences.AdtPrefs;
-import com.android.ide.eclipse.adt.internal.project.AndroidNature;
-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.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-import com.android.io.StreamException;
-import com.android.resources.Density;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
-
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileInfo;
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.filesystem.IFileSystem;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceStatus;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-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.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IAccessRule;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IWorkingSet;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * The actual project creator invoked from the New Project Wizard
- * <p/>
- * Note: this class is public so that it can be accessed from unit tests.
- * It is however an internal class. Its API may change without notice.
- * It should semantically be considered as a private final class.
- */
-public class NewProjectCreator {
-
- private static final String PARAM_SDK_TOOLS_DIR = "ANDROID_SDK_TOOLS"; //$NON-NLS-1$
- private static final String PARAM_ACTIVITY = "ACTIVITY_NAME"; //$NON-NLS-1$
- private static final String PARAM_APPLICATION = "APPLICATION_NAME"; //$NON-NLS-1$
- private static final String PARAM_PACKAGE = "PACKAGE"; //$NON-NLS-1$
- private static final String PARAM_IMPORT_RESOURCE_CLASS = "IMPORT_RESOURCE_CLASS"; //$NON-NLS-1$
- private static final String PARAM_PROJECT = "PROJECT_NAME"; //$NON-NLS-1$
- private static final String PARAM_STRING_NAME = "STRING_NAME"; //$NON-NLS-1$
- private static final String PARAM_STRING_CONTENT = "STRING_CONTENT"; //$NON-NLS-1$
- private static final String PARAM_IS_NEW_PROJECT = "IS_NEW_PROJECT"; //$NON-NLS-1$
- private static final String PARAM_SAMPLE_LOCATION = "SAMPLE_LOCATION"; //$NON-NLS-1$
- private static final String PARAM_SOURCE = "SOURCE"; //$NON-NLS-1$
- private static final String PARAM_SRC_FOLDER = "SRC_FOLDER"; //$NON-NLS-1$
- private static final String PARAM_SDK_TARGET = "SDK_TARGET"; //$NON-NLS-1$
- private static final String PARAM_IS_LIBRARY = "IS_LIBRARY"; //$NON-NLS-1$
- private static final String PARAM_MIN_SDK_VERSION = "MIN_SDK_VERSION"; //$NON-NLS-1$
- // Warning: The expanded string PARAM_TEST_TARGET_PACKAGE must not contain the
- // string "PACKAGE" since it collides with the replacement of PARAM_PACKAGE.
- private static final String PARAM_TEST_TARGET_PACKAGE = "TEST_TARGET_PCKG"; //$NON-NLS-1$
- private static final String PARAM_TARGET_SELF = "TARGET_SELF"; //$NON-NLS-1$
- private static final String PARAM_TARGET_MAIN = "TARGET_MAIN"; //$NON-NLS-1$
- private static final String PARAM_TARGET_EXISTING = "TARGET_EXISTING"; //$NON-NLS-1$
- private static final String PARAM_REFERENCE_PROJECT = "REFERENCE_PROJECT"; //$NON-NLS-1$
-
- private static final String PH_ACTIVITIES = "ACTIVITIES"; //$NON-NLS-1$
- private static final String PH_USES_SDK = "USES-SDK"; //$NON-NLS-1$
- private static final String PH_INTENT_FILTERS = "INTENT_FILTERS"; //$NON-NLS-1$
- private static final String PH_STRINGS = "STRINGS"; //$NON-NLS-1$
- private static final String PH_TEST_USES_LIBRARY = "TEST-USES-LIBRARY"; //$NON-NLS-1$
- private static final String PH_TEST_INSTRUMENTATION = "TEST-INSTRUMENTATION"; //$NON-NLS-1$
-
- private static final String BIN_DIRECTORY =
- SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP;
- private static final String BIN_CLASSES_DIRECTORY =
- SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP +
- SdkConstants.FD_CLASSES_OUTPUT + AdtConstants.WS_SEP;
- private static final String RES_DIRECTORY =
- SdkConstants.FD_RESOURCES + AdtConstants.WS_SEP;
- private static final String ASSETS_DIRECTORY =
- SdkConstants.FD_ASSETS + AdtConstants.WS_SEP;
- private static final String DRAWABLE_DIRECTORY =
- SdkConstants.FD_RES_DRAWABLE + AdtConstants.WS_SEP;
- private static final String DRAWABLE_XHDPI_DIRECTORY =
- SdkConstants.FD_RES_DRAWABLE + '-' + Density.XHIGH.getResourceValue() +
- AdtConstants.WS_SEP;
- private static final String DRAWABLE_HDPI_DIRECTORY =
- SdkConstants.FD_RES_DRAWABLE + '-' + Density.HIGH.getResourceValue() +
- AdtConstants.WS_SEP;
- private static final String DRAWABLE_MDPI_DIRECTORY =
- SdkConstants.FD_RES_DRAWABLE + '-' + Density.MEDIUM.getResourceValue() +
- AdtConstants.WS_SEP;
- private static final String DRAWABLE_LDPI_DIRECTORY =
- SdkConstants.FD_RES_DRAWABLE + '-' + Density.LOW.getResourceValue() +
- AdtConstants.WS_SEP;
- private static final String LAYOUT_DIRECTORY =
- SdkConstants.FD_RES_LAYOUT + AdtConstants.WS_SEP;
- private static final String VALUES_DIRECTORY =
- SdkConstants.FD_RES_VALUES + AdtConstants.WS_SEP;
- private static final String GEN_SRC_DIRECTORY =
- SdkConstants.FD_GEN_SOURCES + AdtConstants.WS_SEP;
-
- private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$
- private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY
- + "AndroidManifest.template"; //$NON-NLS-1$
- private static final String TEMPLATE_ACTIVITIES = TEMPLATES_DIRECTORY
- + "activity.template"; //$NON-NLS-1$
- private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY
- + "uses-sdk.template"; //$NON-NLS-1$
- private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY
- + "launcher_intent_filter.template"; //$NON-NLS-1$
- private static final String TEMPLATE_TEST_USES_LIBRARY = TEMPLATES_DIRECTORY
- + "test_uses-library.template"; //$NON-NLS-1$
- private static final String TEMPLATE_TEST_INSTRUMENTATION = TEMPLATES_DIRECTORY
- + "test_instrumentation.template"; //$NON-NLS-1$
-
-
-
- private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY
- + "strings.template"; //$NON-NLS-1$
- private static final String TEMPLATE_STRING = TEMPLATES_DIRECTORY
- + "string.template"; //$NON-NLS-1$
- private static final String PROJECT_ICON = "ic_launcher.png"; //$NON-NLS-1$
- private static final String ICON_XHDPI = "ic_launcher_xhdpi.png"; //$NON-NLS-1$
- private static final String ICON_HDPI = "ic_launcher_hdpi.png"; //$NON-NLS-1$
- private static final String ICON_MDPI = "ic_launcher_mdpi.png"; //$NON-NLS-1$
- private static final String ICON_LDPI = "ic_launcher_ldpi.png"; //$NON-NLS-1$
-
- private static final String STRINGS_FILE = "strings.xml"; //$NON-NLS-1$
-
- private static final String STRING_RSRC_PREFIX = SdkConstants.STRING_PREFIX;
- private static final String STRING_APP_NAME = "app_name"; //$NON-NLS-1$
- private static final String STRING_HELLO_WORLD = "hello"; //$NON-NLS-1$
-
- private static final String[] DEFAULT_DIRECTORIES = new String[] {
- BIN_DIRECTORY, BIN_CLASSES_DIRECTORY, RES_DIRECTORY, ASSETS_DIRECTORY };
- private static final String[] RES_DIRECTORIES = new String[] {
- DRAWABLE_DIRECTORY, LAYOUT_DIRECTORY, VALUES_DIRECTORY };
- private static final String[] RES_DENSITY_ENABLED_DIRECTORIES = new String[] {
- DRAWABLE_XHDPI_DIRECTORY,
- DRAWABLE_HDPI_DIRECTORY, DRAWABLE_MDPI_DIRECTORY, DRAWABLE_LDPI_DIRECTORY,
- LAYOUT_DIRECTORY, VALUES_DIRECTORY };
-
- private static final String JAVA_ACTIVITY_TEMPLATE = "java_file.template"; //$NON-NLS-1$
- private static final String LAYOUT_TEMPLATE = "layout.template"; //$NON-NLS-1$
- private static final String MAIN_LAYOUT_XML = "main.xml"; //$NON-NLS-1$
-
- private final NewProjectWizardState mValues;
- private final IRunnableContext mRunnableContext;
-
- /**
- * Creates a new {@linkplain NewProjectCreator}
- * @param values the wizard state with initial project parameters
- * @param runnableContext the context to run project creation in
- */
- public NewProjectCreator(NewProjectWizardState values, IRunnableContext runnableContext) {
- mValues = values;
- mRunnableContext = runnableContext;
- }
-
- /**
- * Before actually creating the project for a new project (as opposed to using an
- * existing project), we check if the target location is a directory that either does
- * not exist or is empty.
- *
- * If it's not empty, ask the user for confirmation.
- *
- * @param destination The destination folder where the new project is to be created.
- * @return True if the destination doesn't exist yet or is an empty directory or is
- * accepted by the user.
- */
- private boolean validateNewProjectLocationIsEmpty(IPath destination) {
- File f = new File(destination.toOSString());
- if (f.isDirectory() && f.list().length > 0) {
- return AdtPlugin.displayPrompt("New Android Project",
- "You are going to create a new Android Project in an existing, non-empty, directory. Are you sure you want to proceed?");
- }
- return true;
- }
-
- /**
- * Structure that describes all the information needed to create a project.
- * This is collected from the pages by {@link NewProjectCreator#createAndroidProjects()}
- * and then used by
- * {@link NewProjectCreator#createProjectAsync(IProgressMonitor, ProjectInfo, ProjectInfo)}.
- */
- private static class ProjectInfo {
- private final IProject mProject;
- private final IProjectDescription mDescription;
- private final Map<String, Object> mParameters;
- private final HashMap<String, String> mDictionary;
-
- public ProjectInfo(IProject project,
- IProjectDescription description,
- Map<String, Object> parameters,
- HashMap<String, String> dictionary) {
- mProject = project;
- mDescription = description;
- mParameters = parameters;
- mDictionary = dictionary;
- }
-
- public IProject getProject() {
- return mProject;
- }
-
- public IProjectDescription getDescription() {
- return mDescription;
- }
-
- public Map<String, Object> getParameters() {
- return mParameters;
- }
-
- public HashMap<String, String> getDictionary() {
- return mDictionary;
- }
- }
-
- /**
- * Creates the android project.
- * @return True if the project could be created.
- */
- public boolean createAndroidProjects() {
- if (mValues.importProjects != null && !mValues.importProjects.isEmpty()) {
- return importProjects();
- }
-
- final ProjectInfo mainData = collectMainPageInfo();
- final ProjectInfo testData = collectTestPageInfo();
-
- // Create a monitored operation to create the actual project
- WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
- @Override
- protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
- createProjectAsync(monitor, mainData, testData, null, true);
- }
- };
-
- // Run the operation in a different thread
- runAsyncOperation(op);
- return true;
- }
-
- /**
- * Creates the a plain Java project without typical android directories or an Android Nature.
- * This is intended for use by unit tests and not as a general-purpose Java project creator.
- * @return True if the project could be created.
- */
- @VisibleForTesting
- public boolean createJavaProjects() {
- if (mValues.importProjects != null && !mValues.importProjects.isEmpty()) {
- return importProjects();
- }
-
- final ProjectInfo mainData = collectMainPageInfo();
- final ProjectInfo testData = collectTestPageInfo();
-
- // Create a monitored operation to create the actual project
- WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
- @Override
- protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
- createProjectAsync(monitor, mainData, testData, null, false);
- }
- };
-
- // Run the operation in a different thread
- runAsyncOperation(op);
- return true;
- }
-
- /**
- * Imports a list of projects
- */
- private boolean importProjects() {
- assert mValues.importProjects != null && !mValues.importProjects.isEmpty();
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
-
- final List<ProjectInfo> projectData = new ArrayList<ProjectInfo>();
- for (ImportedProject p : mValues.importProjects) {
-
- // Compute the project name and the package name from the manifest
- ManifestData manifest = p.getManifest();
- if (manifest == null) {
- continue;
- }
- String packageName = manifest.getPackage();
- String projectName = p.getProjectName();
- String minSdk = manifest.getMinSdkVersionString();
-
- final IProject project = workspace.getRoot().getProject(projectName);
- final IProjectDescription description =
- workspace.newProjectDescription(project.getName());
-
- final Map<String, Object> parameters = new HashMap<String, Object>();
- parameters.put(PARAM_PROJECT, projectName);
- parameters.put(PARAM_PACKAGE, packageName);
- parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder());
- parameters.put(PARAM_IS_NEW_PROJECT, Boolean.FALSE);
- parameters.put(PARAM_SRC_FOLDER, SdkConstants.FD_SOURCES);
-
- parameters.put(PARAM_SDK_TARGET, p.getTarget());
-
- // TODO: Find out if these end up getting used in the import-path through the code!
- parameters.put(PARAM_MIN_SDK_VERSION, minSdk);
- parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME);
- final HashMap<String, String> dictionary = new HashMap<String, String>();
- dictionary.put(STRING_APP_NAME, mValues.applicationName);
-
- if (mValues.copyIntoWorkspace) {
- parameters.put(PARAM_SOURCE, p.getLocation());
-
- // TODO: Make sure it isn't *already* in the workspace!
- //IPath defaultLocation = Platform.getLocation();
- //if ((!mValues.useDefaultLocation || mValues.useExisting)
- // && !defaultLocation.isPrefixOf(path)) {
- //IPath workspaceLocation = Platform.getLocation().append(projectName);
- //description.setLocation(workspaceLocation);
- // DON'T SET THE LOCATION: It's IMPLIED and in fact it will generate
- // an error if you set it!
- } else {
- // Create in place
- description.setLocation(new Path(p.getLocation().getPath()));
- }
-
- projectData.add(new ProjectInfo(project, description, parameters, dictionary));
- }
-
- // Create a monitored operation to create the actual project
- WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
- @Override
- protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
- createProjectAsync(monitor, null, null, projectData, true);
- }
- };
-
- // Run the operation in a different thread
- runAsyncOperation(op);
- return true;
- }
-
- /**
- * Collects all the parameters needed to create the main project.
- * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be
- * created because parameters are incorrect or should not be created because there
- * is no main page.
- */
- private ProjectInfo collectMainPageInfo() {
- if (mValues.mode == Mode.TEST) {
- return null;
- }
-
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- final IProject project = workspace.getRoot().getProject(mValues.projectName);
- final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
- final Map<String, Object> parameters = new HashMap<String, Object>();
- parameters.put(PARAM_PROJECT, mValues.projectName);
- parameters.put(PARAM_PACKAGE, mValues.packageName);
- parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME);
- parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder());
- parameters.put(PARAM_IS_NEW_PROJECT, mValues.mode == Mode.ANY && !mValues.useExisting);
- parameters.put(PARAM_SAMPLE_LOCATION, mValues.chosenSample);
- parameters.put(PARAM_SRC_FOLDER, mValues.sourceFolder);
- parameters.put(PARAM_SDK_TARGET, mValues.target);
- parameters.put(PARAM_MIN_SDK_VERSION, mValues.minSdk);
-
- if (mValues.createActivity) {
- parameters.put(PARAM_ACTIVITY, mValues.activityName);
- }
-
- // create a dictionary of string that will contain name+content.
- // we'll put all the strings into values/strings.xml
- final HashMap<String, String> dictionary = new HashMap<String, String>();
- dictionary.put(STRING_APP_NAME, mValues.applicationName);
-
- IPath path = new Path(mValues.projectLocation.getPath());
- IPath defaultLocation = Platform.getLocation();
- if ((!mValues.useDefaultLocation || mValues.useExisting)
- && !defaultLocation.isPrefixOf(path)) {
- description.setLocation(path);
- }
-
- if (mValues.mode == Mode.ANY && !mValues.useExisting && !mValues.useDefaultLocation &&
- !validateNewProjectLocationIsEmpty(path)) {
- return null;
- }
-
- return new ProjectInfo(project, description, parameters, dictionary);
- }
-
- /**
- * Collects all the parameters needed to create the test project.
- *
- * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be
- * created because parameters are incorrect or should not be created because there
- * is no test page.
- */
- private ProjectInfo collectTestPageInfo() {
- if (mValues.mode != Mode.TEST && !mValues.createPairProject) {
- return null;
- }
-
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- String projectName =
- mValues.mode == Mode.TEST ? mValues.projectName : mValues.testProjectName;
- final IProject project = workspace.getRoot().getProject(projectName);
- final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
- final Map<String, Object> parameters = new HashMap<String, Object>();
-
- String pkg =
- mValues.mode == Mode.TEST ? mValues.packageName : mValues.testPackageName;
-
- parameters.put(PARAM_PACKAGE, pkg);
- parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME);
- parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder());
- parameters.put(PARAM_IS_NEW_PROJECT, !mValues.useExisting);
- parameters.put(PARAM_SRC_FOLDER, mValues.sourceFolder);
- parameters.put(PARAM_SDK_TARGET, mValues.target);
- parameters.put(PARAM_MIN_SDK_VERSION, mValues.minSdk);
-
- // Test-specific parameters
- String testedPkg = mValues.createPairProject
- ? mValues.packageName : mValues.testTargetPackageName;
- if (testedPkg == null) {
- assert mValues.testingSelf;
- testedPkg = pkg;
- }
-
- parameters.put(PARAM_TEST_TARGET_PACKAGE, testedPkg);
-
- if (mValues.testingSelf) {
- parameters.put(PARAM_TARGET_SELF, true);
- } else {
- parameters.put(PARAM_TARGET_EXISTING, true);
- parameters.put(PARAM_REFERENCE_PROJECT, mValues.testedProject);
- }
-
- if (mValues.createPairProject) {
- parameters.put(PARAM_TARGET_MAIN, true);
- }
-
- // create a dictionary of string that will contain name+content.
- // we'll put all the strings into values/strings.xml
- final HashMap<String, String> dictionary = new HashMap<String, String>();
- dictionary.put(STRING_APP_NAME, mValues.testApplicationName);
-
- // Use the same logic to determine test project location as in
- // ApplicationInfoPage#validateTestProjectLocation
- IPath path = new Path(mValues.projectLocation.getPath());
- path = path.removeLastSegments(1).append(mValues.testProjectName);
- IPath defaultLocation = Platform.getLocation();
- if ((!mValues.useDefaultLocation || mValues.useExisting)
- && !path.equals(defaultLocation)) {
- description.setLocation(path);
- }
-
- if (!mValues.useExisting && !mValues.useDefaultLocation &&
- !validateNewProjectLocationIsEmpty(path)) {
- return null;
- }
-
- return new ProjectInfo(project, description, parameters, dictionary);
- }
-
- /**
- * Runs the operation in a different thread and display generated
- * exceptions.
- *
- * @param op The asynchronous operation to run.
- */
- private void runAsyncOperation(WorkspaceModifyOperation op) {
- try {
- mRunnableContext.run(true /* fork */, true /* cancelable */, op);
- } catch (InvocationTargetException e) {
-
- AdtPlugin.log(e, "New Project Wizard failed");
-
- // The runnable threw an exception
- Throwable t = e.getTargetException();
- if (t instanceof CoreException) {
- CoreException core = (CoreException) t;
- if (core.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
- // The error indicates the file system is not case sensitive
- // and there's a resource with a similar name.
- MessageDialog.openError(AdtPlugin.getShell(),
- "Error", "Error: Case Variant Exists");
- } else {
- ErrorDialog.openError(AdtPlugin.getShell(),
- "Error", core.getMessage(), core.getStatus());
- }
- } else {
- // Some other kind of exception
- String msg = t.getMessage();
- Throwable t1 = t;
- while (msg == null && t1.getCause() != null) {
- msg = t1.getMessage();
- t1 = t1.getCause();
- }
- if (msg == null) {
- msg = t.toString();
- }
- MessageDialog.openError(AdtPlugin.getShell(), "Error", msg);
- }
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Creates the actual project(s). This is run asynchronously in a different thread.
- *
- * @param monitor An existing monitor.
- * @param mainData Data for main project. Can be null.
- * @param isAndroidProject true if the project is to be set up as a full Android project; false
- * for a plain Java project.
- * @throws InvocationTargetException to wrap any unmanaged exception and
- * return it to the calling thread. The method can fail if it fails
- * to create or modify the project or if it is canceled by the user.
- */
- private void createProjectAsync(IProgressMonitor monitor,
- ProjectInfo mainData,
- ProjectInfo testData,
- List<ProjectInfo> importData,
- boolean isAndroidProject)
- throws InvocationTargetException {
- monitor.beginTask("Create Android Project", 100);
- try {
- IProject mainProject = null;
-
- if (mainData != null) {
- mainProject = createEclipseProject(
- new SubProgressMonitor(monitor, 50),
- mainData.getProject(),
- mainData.getDescription(),
- mainData.getParameters(),
- mainData.getDictionary(),
- null,
- isAndroidProject);
-
- if (mainProject != null) {
- final IJavaProject javaProject = JavaCore.create(mainProject);
- Display.getDefault().syncExec(new WorksetAdder(javaProject,
- mValues.workingSets));
- }
- }
-
- if (testData != null) {
- Map<String, Object> parameters = testData.getParameters();
- if (parameters.containsKey(PARAM_TARGET_MAIN) && mainProject != null) {
- parameters.put(PARAM_REFERENCE_PROJECT, mainProject);
- }
-
- IProject testProject = createEclipseProject(
- new SubProgressMonitor(monitor, 50),
- testData.getProject(),
- testData.getDescription(),
- parameters,
- testData.getDictionary(),
- null,
- isAndroidProject);
- if (testProject != null) {
- final IJavaProject javaProject = JavaCore.create(testProject);
- Display.getDefault().syncExec(new WorksetAdder(javaProject,
- mValues.workingSets));
- }
- }
-
- if (importData != null) {
- for (final ProjectInfo data : importData) {
- ProjectPopulator projectPopulator = null;
- if (mValues.copyIntoWorkspace) {
- projectPopulator = new ProjectPopulator() {
- @Override
- public void populate(IProject project) {
- // Copy
- IFileSystem fileSystem = EFS.getLocalFileSystem();
- File source = (File) data.getParameters().get(PARAM_SOURCE);
- IFileStore sourceDir = new ReadWriteFileStore(
- fileSystem.getStore(source.toURI()));
- IFileStore destDir = new ReadWriteFileStore(
- fileSystem.getStore(AdtUtils.getAbsolutePath(project)));
- try {
- sourceDir.copy(destDir, EFS.OVERWRITE, null);
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
- }
- };
- }
- IProject project = createEclipseProject(
- new SubProgressMonitor(monitor, 50),
- data.getProject(),
- data.getDescription(),
- data.getParameters(),
- data.getDictionary(),
- projectPopulator,
- isAndroidProject);
- if (project != null) {
- final IJavaProject javaProject = JavaCore.create(project);
- Display.getDefault().syncExec(new WorksetAdder(javaProject,
- mValues.workingSets));
- ProjectHelper.enforcePreferredCompilerCompliance(javaProject);
- }
- }
- }
- } catch (CoreException e) {
- throw new InvocationTargetException(e);
- } catch (IOException e) {
- throw new InvocationTargetException(e);
- } catch (StreamException e) {
- throw new InvocationTargetException(e);
- } finally {
- monitor.done();
- }
- }
-
- /** Handler which can write contents into a project */
- public interface ProjectPopulator {
- /**
- * Add contents into the given project
- *
- * @param project the project to write into
- * @throws InvocationTargetException if anything goes wrong
- */
- public void populate(IProject project) throws InvocationTargetException;
- }
-
- /**
- * Creates the actual project, sets its nature and adds the required folders
- * and files to it. This is run asynchronously in a different thread.
- *
- * @param monitor An existing monitor.
- * @param project The project to create.
- * @param description A description of the project.
- * @param parameters Template parameters.
- * @param dictionary String definition.
- * @param isAndroidProject true if the project is to be set up as a full Android project; false
- * for a plain Java project.
- * @return The project newly created
- * @throws StreamException
- */
- private IProject createEclipseProject(
- @NonNull IProgressMonitor monitor,
- @NonNull IProject project,
- @NonNull IProjectDescription description,
- @NonNull Map<String, Object> parameters,
- @Nullable Map<String, String> dictionary,
- @Nullable ProjectPopulator projectPopulator,
- boolean isAndroidProject)
- throws CoreException, IOException, StreamException {
-
- // get the project target
- IAndroidTarget target = (IAndroidTarget) parameters.get(PARAM_SDK_TARGET);
- boolean legacy = isAndroidProject && target.getVersion().getApiLevel() < 4;
-
- // Create project and open it
- project.create(description, new SubProgressMonitor(monitor, 10));
- if (monitor.isCanceled()) throw new OperationCanceledException();
-
- project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 10));
-
- // Add the Java and android nature to the project
- AndroidNature.setupProjectNatures(project, monitor, isAndroidProject);
-
- // Create folders in the project if they don't already exist
- addDefaultDirectories(project, AdtConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor);
- String[] sourceFolders;
- if (isAndroidProject) {
- sourceFolders = new String[] {
- (String) parameters.get(PARAM_SRC_FOLDER),
- GEN_SRC_DIRECTORY
- };
- } else {
- sourceFolders = new String[] {
- (String) parameters.get(PARAM_SRC_FOLDER)
- };
- }
- addDefaultDirectories(project, AdtConstants.WS_ROOT, sourceFolders, monitor);
-
- // Create the resource folders in the project if they don't already exist.
- if (legacy) {
- addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor);
- } else {
- addDefaultDirectories(project, RES_DIRECTORY, RES_DENSITY_ENABLED_DIRECTORIES, monitor);
- }
-
- if (projectPopulator != null) {
- try {
- projectPopulator.populate(project);
- } catch (InvocationTargetException ite) {
- AdtPlugin.log(ite, null);
- }
- }
-
- // Setup class path: mark folders as source folders
- IJavaProject javaProject = JavaCore.create(project);
- setupSourceFolders(javaProject, sourceFolders, monitor);
-
- if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) {
- // Create files in the project if they don't already exist
- addManifest(project, parameters, dictionary, monitor);
-
- // add the default app icon
- addIcon(project, legacy, monitor);
-
- // Create the default package components
- addSampleCode(project, sourceFolders[0], parameters, dictionary, monitor);
-
- // add the string definition file if needed
- if (dictionary != null && dictionary.size() > 0) {
- addStringDictionaryFile(project, dictionary, monitor);
- }
-
- // add the default proguard config
- File libFolder = new File((String) parameters.get(PARAM_SDK_TOOLS_DIR),
- SdkConstants.FD_LIB);
- 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,
- monitor);
-
- // Set output location
- javaProject.setOutputLocation(project.getFolder(BIN_CLASSES_DIRECTORY).getFullPath(),
- monitor);
- }
-
- File sampleDir = (File) parameters.get(PARAM_SAMPLE_LOCATION);
- if (sampleDir != null) {
- // Copy project
- copySampleCode(project, sampleDir, parameters, dictionary, monitor);
- }
-
- // Create the reference to the target project
- if (parameters.containsKey(PARAM_REFERENCE_PROJECT)) {
- IProject refProject = (IProject) parameters.get(PARAM_REFERENCE_PROJECT);
- if (refProject != null) {
- IProjectDescription desc = project.getDescription();
-
- // Add out reference to the existing project reference.
- // We just created a project with no references so we don't need to expand
- // the currently-empty current list.
- desc.setReferencedProjects(new IProject[] { refProject });
-
- project.setDescription(desc, IResource.KEEP_HISTORY,
- new SubProgressMonitor(monitor, 10));
-
- IClasspathEntry entry = JavaCore.newProjectEntry(
- refProject.getFullPath(), //path
- new IAccessRule[0], //accessRules
- false, //combineAccessRules
- new IClasspathAttribute[0], //extraAttributes
- false //isExported
-
- );
- ProjectHelper.addEntryToClasspath(javaProject, entry);
- }
- }
-
- if (isAndroidProject) {
- Sdk.getCurrent().initProject(project, target);
- }
-
- // Fix the project to make sure all properties are as expected.
- // Necessary for existing projects and good for new ones to.
- ProjectHelper.fixProject(project);
-
- Boolean isLibraryProject = (Boolean) parameters.get(PARAM_IS_LIBRARY);
- if (isLibraryProject != null && isLibraryProject.booleanValue()
- && Sdk.getCurrent() != null && project.isOpen()) {
- ProjectState state = Sdk.getProjectState(project);
- if (state != null) {
- // make a working copy of the properties
- ProjectPropertiesWorkingCopy properties =
- state.getProperties().makeWorkingCopy();
-
- properties.setProperty(PROPERTY_LIBRARY, Boolean.TRUE.toString());
- try {
- properties.save();
- IResource projectProp = project.findMember(FN_PROJECT_PROPERTIES);
- if (projectProp != null) {
- projectProp.refreshLocal(DEPTH_ZERO, new NullProgressMonitor());
- }
- } catch (Exception e) {
- String msg = String.format(
- "Failed to save %1$s for project %2$s",
- SdkConstants.FN_PROJECT_PROPERTIES, project.getName());
- AdtPlugin.log(e, msg);
- }
- }
- }
-
- return project;
- }
-
- /**
- * Creates a new project
- *
- * @param monitor An existing monitor.
- * @param project The project to create.
- * @param target the build target to associate with the project
- * @param projectPopulator a handler for writing the template contents
- * @param isLibrary whether this project should be marked as a library project
- * @param projectLocation the location to write the project into
- * @param workingSets Eclipse working sets, if any, to add the project to
- * @throws CoreException if anything goes wrong
- */
- public static void create(
- @NonNull IProgressMonitor monitor,
- @NonNull final IProject project,
- @NonNull IAndroidTarget target,
- @Nullable final ProjectPopulator projectPopulator,
- boolean isLibrary,
- @NonNull String projectLocation,
- @NonNull final IWorkingSet[] workingSets)
- throws CoreException {
- final NewProjectCreator creator = new NewProjectCreator(null, null);
-
- final Map<String, String> dictionary = null;
- final Map<String, Object> parameters = new HashMap<String, Object>();
- parameters.put(PARAM_SDK_TARGET, target);
- parameters.put(PARAM_SRC_FOLDER, SdkConstants.FD_SOURCES);
- parameters.put(PARAM_IS_NEW_PROJECT, false);
- parameters.put(PARAM_SAMPLE_LOCATION, null);
- parameters.put(PARAM_IS_LIBRARY, isLibrary);
-
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
- if (projectLocation != null) {
- IPath path = new Path(projectLocation);
- IPath parent = new Path(path.toFile().getParent());
- IPath workspaceLocation = Platform.getLocation();
- if (!workspaceLocation.equals(parent)) {
- description.setLocation(path);
- }
- }
-
- IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
- @Override
- public void run(IProgressMonitor submonitor) throws CoreException {
- try {
- creator.createEclipseProject(submonitor, project, description, parameters,
- dictionary, projectPopulator, true);
- } catch (IOException e) {
- throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Unexpected error while creating project", e));
- } catch (StreamException e) {
- throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Unexpected error while creating project", e));
- }
- if (workingSets != null && workingSets.length > 0) {
- IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
- if (javaProject != null) {
- Display.getDefault().syncExec(new WorksetAdder(javaProject,
- workingSets));
- }
- }
- }
- };
-
- ResourcesPlugin.getWorkspace().run(workspaceRunnable, monitor);
- }
-
- /**
- * Adds default directories to the project.
- *
- * @param project The Java Project to update.
- * @param parentFolder The path of the parent folder. Must end with a
- * separator.
- * @param folders Folders to be added.
- * @param monitor An existing monitor.
- * @throws CoreException if the method fails to create the directories in
- * the project.
- */
- private void addDefaultDirectories(IProject project, String parentFolder,
- String[] folders, IProgressMonitor monitor) throws CoreException {
- for (String name : folders) {
- if (name.length() > 0) {
- IFolder folder = project.getFolder(parentFolder + name);
- if (!folder.exists()) {
- folder.create(true /* force */, true /* local */,
- new SubProgressMonitor(monitor, 10));
- }
- }
- }
- }
-
- /**
- * Adds the manifest to the project.
- *
- * @param project The Java Project to update.
- * @param parameters Template Parameters.
- * @param dictionary String List to be added to a string definition
- * file. This map will be filled by this method.
- * @param monitor An existing monitor.
- * @throws CoreException if the method fails to update the project.
- * @throws IOException if the method fails to create the files in the
- * project.
- */
- private void addManifest(IProject project, Map<String, Object> parameters,
- Map<String, String> dictionary, IProgressMonitor monitor)
- throws CoreException, IOException {
-
- // get IFile to the manifest and check if it's not already there.
- IFile file = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
- if (!file.exists()) {
-
- // Read manifest template
- String manifestTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_MANIFEST);
-
- // Replace all keyword parameters
- manifestTemplate = replaceParameters(manifestTemplate, parameters);
-
- if (manifestTemplate == null) {
- // Inform the user there will be not manifest.
- AdtPlugin.logAndPrintError(null, "Create Project" /*TAG*/,
- "Failed to generate the Android manifest. Missing template %s",
- TEMPLATE_MANIFEST);
- // Abort now, there's no need to continue
- return;
- }
-
- if (parameters.containsKey(PARAM_ACTIVITY)) {
- // now get the activity template
- String activityTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_ACTIVITIES);
-
- // If the activity name doesn't contain any dot, it's in the form
- // "ClassName" and we need to expand it to ".ClassName" in the XML.
- String name = (String) parameters.get(PARAM_ACTIVITY);
- if (name.indexOf('.') == -1) {
- // Duplicate the parameters map to avoid changing the caller
- parameters = new HashMap<String, Object>(parameters);
- parameters.put(PARAM_ACTIVITY, "." + name); //$NON-NLS-1$
- }
-
- // Replace all keyword parameters to make main activity.
- String activities = replaceParameters(activityTemplate, parameters);
-
- // set the intent.
- String intent = AdtPlugin.readEmbeddedTextFile(TEMPLATE_INTENT_LAUNCHER);
-
- if (activities != null) {
- if (intent != null) {
- // set the intent to the main activity
- activities = activities.replaceAll(PH_INTENT_FILTERS, intent);
- }
-
- // set the activity(ies) in the manifest
- manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, activities);
- }
- } else {
- // remove the activity(ies) from the manifest
- manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, ""); //$NON-NLS-1$
- }
-
- // Handle the case of the test projects
- if (parameters.containsKey(PARAM_TEST_TARGET_PACKAGE)) {
- // Set the uses-library needed by the test project
- String usesLibrary = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_USES_LIBRARY);
- if (usesLibrary != null) {
- manifestTemplate = manifestTemplate.replaceAll(
- PH_TEST_USES_LIBRARY, usesLibrary);
- }
-
- // Set the instrumentation element needed by the test project
- String instru = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_INSTRUMENTATION);
- if (instru != null) {
- manifestTemplate = manifestTemplate.replaceAll(
- PH_TEST_INSTRUMENTATION, instru);
- }
-
- // Replace PARAM_TEST_TARGET_PACKAGE itself now
- manifestTemplate = replaceParameters(manifestTemplate, parameters);
-
- } else {
- // remove the unused entries
- manifestTemplate = manifestTemplate.replaceAll(PH_TEST_USES_LIBRARY, ""); //$NON-NLS-1$
- manifestTemplate = manifestTemplate.replaceAll(PH_TEST_INSTRUMENTATION, ""); //$NON-NLS-1$
- }
-
- String minSdkVersion = (String) parameters.get(PARAM_MIN_SDK_VERSION);
- if (minSdkVersion != null && minSdkVersion.length() > 0) {
- String usesSdkTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_USES_SDK);
- if (usesSdkTemplate != null) {
- String usesSdk = replaceParameters(usesSdkTemplate, parameters);
- manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, usesSdk);
- }
- } else {
- manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, "");
- }
-
- // Reformat the file according to the user's formatting settings
- manifestTemplate = reformat(XmlFormatStyle.MANIFEST, manifestTemplate);
-
- // Save in the project as UTF-8
- InputStream stream = new ByteArrayInputStream(
- manifestTemplate.getBytes("UTF-8")); //$NON-NLS-1$
- file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
- }
- }
-
- /**
- * Adds the string resource file.
- *
- * @param project The Java Project to update.
- * @param strings The list of strings to be added to the string file.
- * @param monitor An existing monitor.
- * @throws CoreException if the method fails to update the project.
- * @throws IOException if the method fails to create the files in the
- * project.
- */
- private void addStringDictionaryFile(IProject project,
- Map<String, String> strings, IProgressMonitor monitor)
- throws CoreException, IOException {
-
- // create the IFile object and check if the file doesn't already exist.
- IFile file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + VALUES_DIRECTORY + AdtConstants.WS_SEP + STRINGS_FILE);
- if (!file.exists()) {
- // get the Strings.xml template
- String stringDefinitionTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRINGS);
-
- // get the template for one string
- String stringTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRING);
-
- // get all the string names
- Set<String> stringNames = strings.keySet();
-
- // loop on it and create the string definitions
- StringBuilder stringNodes = new StringBuilder();
- for (String key : stringNames) {
- // get the value from the key
- String value = strings.get(key);
-
- // Escape values if necessary
- value = ValueXmlHelper.escapeResourceString(value);
-
- // place them in the template
- String stringDef = stringTemplate.replace(PARAM_STRING_NAME, key);
- stringDef = stringDef.replace(PARAM_STRING_CONTENT, value);
-
- // append to the other string
- if (stringNodes.length() > 0) {
- stringNodes.append('\n');
- }
- stringNodes.append(stringDef);
- }
-
- // put the string nodes in the Strings.xml template
- stringDefinitionTemplate = stringDefinitionTemplate.replace(PH_STRINGS,
- stringNodes.toString());
-
- // reformat the file according to the user's formatting settings
- stringDefinitionTemplate = reformat(XmlFormatStyle.RESOURCE, stringDefinitionTemplate);
-
- // write the file as UTF-8
- InputStream stream = new ByteArrayInputStream(
- stringDefinitionTemplate.getBytes("UTF-8")); //$NON-NLS-1$
- file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
- }
- }
-
- /** Reformats the given contents with the current formatting settings */
- private String reformat(XmlFormatStyle style, String contents) {
- if (AdtPrefs.getPrefs().getUseCustomXmlFormatter()) {
- EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
- return EclipseXmlPrettyPrinter.prettyPrint(contents, formatPrefs, style,
- null /*lineSeparator*/);
- } else {
- return contents;
- }
- }
-
- /**
- * Adds default application icon to the project.
- *
- * @param project The Java Project to update.
- * @param legacy whether we're running in legacy mode (no density support)
- * @param monitor An existing monitor.
- * @throws CoreException if the method fails to update the project.
- */
- private void addIcon(IProject project, boolean legacy, IProgressMonitor monitor)
- throws CoreException {
- if (legacy) { // density support
- // do medium density icon only, in the default drawable folder.
- IFile file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + DRAWABLE_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON);
- if (!file.exists()) {
- addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor);
- }
- } else {
- // do all 4 icons.
- IFile file;
-
- // extra high density
- file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + DRAWABLE_XHDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON);
- if (!file.exists()) {
- addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_XHDPI), monitor);
- }
-
- // high density
- file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + DRAWABLE_HDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON);
- if (!file.exists()) {
- addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_HDPI), monitor);
- }
-
- // medium density
- file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + DRAWABLE_MDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON);
- if (!file.exists()) {
- addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor);
- }
-
- // low density
- file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP
- + DRAWABLE_LDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON);
- if (!file.exists()) {
- addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_LDPI), monitor);
- }
- }
- }
-
- /**
- * Creates a file from a data source.
- * @param dest the file to write
- * @param source the content of the file.
- * @param monitor the progress monitor
- * @throws CoreException
- */
- private void addFile(IFile dest, byte[] source, IProgressMonitor monitor) throws CoreException {
- if (source != null) {
- // Save in the project
- InputStream stream = new ByteArrayInputStream(source);
- dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
- }
- }
-
- /**
- * Creates the package folder and copies the sample code in the project.
- *
- * @param project The Java Project to update.
- * @param parameters Template Parameters.
- * @param dictionary String List to be added to a string definition
- * file. This map will be filled by this method.
- * @param monitor An existing monitor.
- * @throws CoreException if the method fails to update the project.
- * @throws IOException if the method fails to create the files in the
- * project.
- */
- private void addSampleCode(IProject project, String sourceFolder,
- Map<String, Object> parameters, Map<String, String> dictionary,
- IProgressMonitor monitor) throws CoreException, IOException {
- // create the java package directories.
- IFolder pkgFolder = project.getFolder(sourceFolder);
- String packageName = (String) parameters.get(PARAM_PACKAGE);
-
- // The PARAM_ACTIVITY key will be absent if no activity should be created,
- // in which case activityName will be null.
- String activityName = (String) parameters.get(PARAM_ACTIVITY);
-
- Map<String, Object> java_activity_parameters = new HashMap<String, Object>(parameters);
- java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, ""); //$NON-NLS-1$
-
- if (activityName != null) {
-
- String resourcePackageClass = null;
-
- // An activity name can be of the form ".package.Class", ".Class" or FQDN.
- // The initial dot is ignored, as it is always added later in the templates.
- int lastDotIndex = activityName.lastIndexOf('.');
-
- if (lastDotIndex != -1) {
-
- // Resource class
- if (lastDotIndex > 0) {
- resourcePackageClass = packageName + '.' + SdkConstants.FN_RESOURCE_BASE;
- }
-
- // Package name
- if (activityName.startsWith(".")) { //$NON-NLS-1$
- packageName += activityName.substring(0, lastDotIndex);
- } else {
- packageName = activityName.substring(0, lastDotIndex);
- }
-
- // Activity Class name
- activityName = activityName.substring(lastDotIndex + 1);
- }
-
- java_activity_parameters.put(PARAM_ACTIVITY, activityName);
- java_activity_parameters.put(PARAM_PACKAGE, packageName);
- if (resourcePackageClass != null) {
- String importResourceClass = "\nimport " + resourcePackageClass + ";"; //$NON-NLS-1$ // $NON-NLS-2$
- java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, importResourceClass);
- }
- }
-
- String[] components = packageName.split(AdtConstants.RE_DOT);
- for (String component : components) {
- pkgFolder = pkgFolder.getFolder(component);
- if (!pkgFolder.exists()) {
- pkgFolder.create(true /* force */, true /* local */,
- new SubProgressMonitor(monitor, 10));
- }
- }
-
- if (activityName != null) {
- // create the main activity Java file
- String activityJava = activityName + SdkConstants.DOT_JAVA;
- IFile file = pkgFolder.getFile(activityJava);
- if (!file.exists()) {
- copyFile(JAVA_ACTIVITY_TEMPLATE, file, java_activity_parameters, monitor, false);
- }
-
- // create the layout file (if we're creating an
- IFolder layoutfolder = project.getFolder(RES_DIRECTORY).getFolder(LAYOUT_DIRECTORY);
- file = layoutfolder.getFile(MAIN_LAYOUT_XML);
- if (!file.exists()) {
- copyFile(LAYOUT_TEMPLATE, file, parameters, monitor, true);
- dictionary.put(STRING_HELLO_WORLD, String.format("Hello World, %1$s!",
- activityName));
- }
- }
- }
-
- private void copySampleCode(IProject project, File sampleDir,
- Map<String, Object> parameters, Map<String, String> dictionary,
- IProgressMonitor monitor) throws CoreException {
- // Copy the sampleDir into the project directory recursively
- IFileSystem fileSystem = EFS.getLocalFileSystem();
- IFileStore sourceDir = new ReadWriteFileStore(
- fileSystem.getStore(sampleDir.toURI()));
- IFileStore destDir = new ReadWriteFileStore(
- fileSystem.getStore(AdtUtils.getAbsolutePath(project)));
- sourceDir.copy(destDir, EFS.OVERWRITE, null);
- }
-
- /**
- * In a sample we never duplicate source files as read-only.
- * This creates a store that read files attributes and doesn't set the r-o flag.
- */
- private static class ReadWriteFileStore extends FileStoreAdapter {
-
- public ReadWriteFileStore(IFileStore store) {
- super(store);
- }
-
- // Override when reading attributes
- @Override
- public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
- IFileInfo info = super.fetchInfo(options, monitor);
- info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false);
- return info;
- }
-
- // Override when writing attributes
- @Override
- public void putInfo(IFileInfo info, int options, IProgressMonitor storeMonitor)
- throws CoreException {
- info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false);
- super.putInfo(info, options, storeMonitor);
- }
-
- @Deprecated
- @Override
- public IFileStore getChild(IPath path) {
- IFileStore child = super.getChild(path);
- if (!(child instanceof ReadWriteFileStore)) {
- child = new ReadWriteFileStore(child);
- }
- return child;
- }
-
- @Override
- public IFileStore getChild(String name) {
- return new ReadWriteFileStore(super.getChild(name));
- }
- }
-
- /**
- * Adds a file to the root of the project
- * @param project the project to add the file to.
- * @param destName the name to write the file as
- * @param source the file to add. It'll keep the same filename once copied into the project.
- * @param monitor the monitor to report progress to
- * @throws FileNotFoundException if the file to be added does not exist
- * @throws CoreException if writing the file does not work
- */
- public static void addLocalFile(IProject project, File source, String destName,
- IProgressMonitor monitor) throws FileNotFoundException, CoreException {
- IFile dest = project.getFile(destName);
- if (dest.exists() == false) {
- FileInputStream stream = new FileInputStream(source);
- dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
- }
- }
-
- /**
- * Adds the given folder to the project's class path.
- *
- * @param javaProject The Java Project to update.
- * @param sourceFolders Template Parameters.
- * @param monitor An existing monitor.
- * @throws JavaModelException if the classpath could not be set.
- */
- private void setupSourceFolders(IJavaProject javaProject, String[] sourceFolders,
- IProgressMonitor monitor) throws JavaModelException {
- IProject project = javaProject.getProject();
-
- // get the list of entries.
- IClasspathEntry[] entries = javaProject.getRawClasspath();
-
- // remove the project as a source folder (This is the default)
- entries = removeSourceClasspath(entries, project);
-
- // add the source folders.
- for (String sourceFolder : sourceFolders) {
- IFolder srcFolder = project.getFolder(sourceFolder);
-
- // remove it first in case.
- entries = removeSourceClasspath(entries, srcFolder);
- entries = ProjectHelper.addEntryToClasspath(entries,
- JavaCore.newSourceEntry(srcFolder.getFullPath()));
- }
-
- javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10));
- }
-
-
- /**
- * Removes the corresponding source folder from the class path entries if
- * found.
- *
- * @param entries The class path entries to read. A copy will be returned.
- * @param folder The parent source folder to remove.
- * @return A new class path entries array.
- */
- private IClasspathEntry[] removeSourceClasspath(IClasspathEntry[] entries, IContainer folder) {
- if (folder == null) {
- return entries;
- }
- IClasspathEntry source = JavaCore.newSourceEntry(folder.getFullPath());
- int n = entries.length;
- for (int i = n - 1; i >= 0; i--) {
- if (entries[i].equals(source)) {
- IClasspathEntry[] newEntries = new IClasspathEntry[n - 1];
- if (i > 0) System.arraycopy(entries, 0, newEntries, 0, i);
- if (i < n - 1) System.arraycopy(entries, i + 1, newEntries, i, n - i - 1);
- n--;
- entries = newEntries;
- }
- }
- return entries;
- }
-
-
- /**
- * Copies the given file from our resource folder to the new project.
- * Expects the file to the US-ASCII or UTF-8 encoded.
- *
- * @throws CoreException from IFile if failing to create the new file.
- * @throws MalformedURLException from URL if failing to interpret the URL.
- * @throws FileNotFoundException from RandomAccessFile.
- * @throws IOException from RandomAccessFile.length() if can't determine the
- * length.
- */
- private void copyFile(String resourceFilename, IFile destFile,
- Map<String, Object> parameters, IProgressMonitor monitor, boolean reformat)
- throws CoreException, IOException {
-
- // Read existing file.
- String template = AdtPlugin.readEmbeddedTextFile(
- TEMPLATES_DIRECTORY + resourceFilename);
-
- // Replace all keyword parameters
- template = replaceParameters(template, parameters);
-
- if (reformat) {
- // Guess the formatting style based on the file location
- XmlFormatStyle style = EclipseXmlPrettyPrinter
- .getForFile(destFile.getProjectRelativePath());
- if (style != null) {
- template = reformat(style, template);
- }
- }
-
- // Save in the project as UTF-8
- InputStream stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$
- destFile.create(stream, false /* force */, new SubProgressMonitor(monitor, 10));
- }
-
- /**
- * Replaces placeholders found in a string with values.
- *
- * @param str the string to search for placeholders.
- * @param parameters a map of <placeholder, Value> to search for in the string
- * @return A new String object with the placeholder replaced by the values.
- */
- private String replaceParameters(String str, Map<String, Object> parameters) {
-
- if (parameters == null) {
- AdtPlugin.log(IStatus.ERROR,
- "NPW replace parameters: null parameter map. String: '%s'", str); //$NON-NLS-1$
- return str;
- } else if (str == null) {
- AdtPlugin.log(IStatus.ERROR,
- "NPW replace parameters: null template string"); //$NON-NLS-1$
- return str;
- }
-
- for (Entry<String, Object> entry : parameters.entrySet()) {
- if (entry != null && entry.getValue() instanceof String) {
- Object value = entry.getValue();
- if (value == null) {
- AdtPlugin.log(IStatus.ERROR,
- "NPW replace parameters: null value for key '%s' in template '%s'", //$NON-NLS-1$
- entry.getKey(),
- str);
- } else {
- str = str.replaceAll(entry.getKey(), (String) value);
- }
- }
- }
-
- return str;
- }
-
- private static class WorksetAdder implements Runnable {
- private final IJavaProject mProject;
- private final IWorkingSet[] mWorkingSets;
-
- private WorksetAdder(IJavaProject project, IWorkingSet[] workingSets) {
- mProject = project;
- mWorkingSets = workingSets;
- }
-
- @Override
- public void run() {
- if (mWorkingSets.length > 0 && mProject != null
- && mProject.exists()) {
- PlatformUI.getWorkbench().getWorkingSetManager()
- .addToWorkingSets(mProject, mWorkingSets);
- }
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java
deleted file mode 100644
index ff03b338f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
-import static com.android.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-
-import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
-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.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-
-import java.io.File;
-
-
-/**
- * A "New Android Project" Wizard.
- * <p/>
- * Note: this class is public so that it can be accessed from unit tests.
- * It is however an internal class. Its API may change without notice.
- * It should semantically be considered as a private final class.
- * <p/>
- * Do not derive from this class.
- */
-public class NewProjectWizard extends Wizard implements INewWizard {
- private static final String PROJECT_LOGO_LARGE = "icons/android-64.png"; //$NON-NLS-1$
-
- private NewProjectWizardState mValues;
- private ProjectNamePage mNamePage;
- private SdkSelectionPage mSdkPage;
- private SampleSelectionPage mSamplePage;
- private ApplicationInfoPage mPropertiesPage;
- private final Mode mMode;
- private IStructuredSelection mSelection;
-
- /** Constructs a new wizard default project wizard */
- public NewProjectWizard() {
- this(Mode.ANY);
- }
-
- protected NewProjectWizard(Mode mode) {
- mMode = mode;
- switch (mMode) {
- case SAMPLE:
- setWindowTitle("New Android Sample Project");
- break;
- case TEST:
- setWindowTitle("New Android Test Project");
- break;
- default:
- setWindowTitle("New Android Project");
- break;
- }
- }
-
- @Override
- public void addPages() {
- mValues = new NewProjectWizardState(mMode);
-
- if (mMode != Mode.SAMPLE) {
- mNamePage = new ProjectNamePage(mValues);
-
- if (mSelection != null) {
- mNamePage.init(mSelection, AdtUtils.getActivePart());
- }
-
- addPage(mNamePage);
- }
-
- if (mMode == Mode.TEST) {
- addPage(new TestTargetPage(mValues));
- }
-
- mSdkPage = new SdkSelectionPage(mValues);
- addPage(mSdkPage);
-
- if (mMode != Mode.TEST) {
- // Sample projects can be created when entering the new/existing wizard, or
- // the sample wizard
- mSamplePage = new SampleSelectionPage(mValues);
- addPage(mSamplePage);
- }
-
- if (mMode != Mode.SAMPLE) {
- // Project properties are entered in all project types except sample projects
- mPropertiesPage = new ApplicationInfoPage(mValues);
- addPage(mPropertiesPage);
- }
- }
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- mSelection = selection;
-
- setHelpAvailable(false); // TODO have help
- ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
- setDefaultPageImageDescriptor(desc);
-
- // Trigger a check to see if the SDK needs to be reloaded (which will
- // invoke onSdkLoaded asynchronously as needed).
- AdtPlugin.getDefault().refreshSdk();
- }
-
- @Override
- public boolean performFinish() {
- File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER + File.separator
- + FN_PROJECT_PROGUARD_FILE);
- if (!file.exists()) {
- AdtPlugin.displayError("Tools Out of Date?",
- String.format("It looks like you do not have the latest version of the "
- + "SDK Tools installed. Make sure you update via the SDK Manager "
- + "first. (Could not find %1$s)", file.getPath()));
- return false;
- }
-
- NewProjectCreator creator = new NewProjectCreator(mValues, getContainer());
- if (!(creator.createAndroidProjects())) {
- return false;
- }
-
- // Open the default Java Perspective
- OpenJavaPerspectiveAction action = new OpenJavaPerspectiveAction();
- action.run();
- return true;
- }
-
- @Override
- public IWizardPage getNextPage(IWizardPage page) {
- if (page == mNamePage) {
- // Skip the test target selection page unless creating a test project
- if (mValues.mode != Mode.TEST) {
- return mSdkPage;
- }
- } else if (page == mSdkPage) {
- if (mValues.mode == Mode.SAMPLE) {
- return mSamplePage;
- } else if (mValues.mode != Mode.TEST) {
- return mPropertiesPage;
- } else {
- // Done with wizard when creating from existing or creating test projects
- return null;
- }
- } else if (page == mSamplePage) {
- // Nothing more to be entered for samples
- return null;
- }
-
- return super.getNextPage(page);
- }
-
- /**
- * Returns the package name currently set by the wizard
- *
- * @return the current package name, or null
- */
- public String getPackageName() {
- return mValues.packageName;
- }
-
- // TBD: Call setDialogSettings etc to store persistent state between wizard invocations.
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java
deleted file mode 100644
index 06c0300b7..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.SdkConstants;
-import com.android.annotations.Nullable;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.common.xml.ManifestData.Activity;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
-import com.android.utils.Pair;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.ui.IWorkingSet;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The {@link NewProjectWizardState} holds the state used by the various pages
- * in the {@link NewProjectWizard} and its variations, and it can also be used
- * to pass project information to the {@link NewProjectCreator}.
- */
-public class NewProjectWizardState {
- /** The mode to run the wizard in: creating test, or sample, or plain project */
- public Mode mode;
-
- /**
- * If true, the project should be created from an existing codebase (pointed
- * to by the {@link #projectLocation} or in the case of sample projects, the
- * {@link #chosenSample}. Otherwise, create a brand new project from scratch.
- */
- public boolean useExisting;
-
- /**
- * Whether new projects should be created into the default project location
- * (e.g. in the Eclipse workspace) or not
- */
- public boolean useDefaultLocation = true;
-
- /** The build target SDK */
- public IAndroidTarget target;
- /** True if the user has manually modified the target */
- public boolean targetModifiedByUser;
-
- /** The location to store projects into */
- public File projectLocation = new File(Platform.getLocation().toOSString());
- /** True if the project location name has been manually edited by the user */
- public boolean projectLocationModifiedByUser;
-
- /** The name of the project */
- public String projectName = ""; //$NON-NLS-1$
- /** True if the project name has been manually edited by the user */
- public boolean projectNameModifiedByUser;
-
- /** The application name */
- public String applicationName;
- /** True if the application name has been manually edited by the user */
- public boolean applicationNameModifiedByUser;
-
- /** The package path */
- public String packageName;
- /** True if the package name has been manually edited by the user */
- public boolean packageNameModifiedByUser;
-
- /** True if a new activity should be created */
- public boolean createActivity;
-
- /** The name of the new activity to be created */
- public String activityName;
- /** True if the activity name has been manually edited by the user */
- public boolean activityNameModifiedByUser;
-
- /** The minimum SDK version to use with the project (may be null or blank) */
- public String minSdk;
- /** True if the minimum SDK version has been manually edited by the user */
- public boolean minSdkModifiedByUser;
- /**
- * A list of paths to each of the available samples for the current SDK.
- * The pair is (String: sample display name => File: sample directory).
- * Note we want a list, not a map since we might have duplicates.
- * */
- public List<Pair<String, File>> samples = new ArrayList<Pair<String, File>>();
- /** Path to the currently chosen sample */
- public File chosenSample;
-
- /** The name of the source folder, relative to the project root */
- public String sourceFolder = SdkConstants.FD_SOURCES;
- /** The set of chosen working sets to use when creating the project */
- public IWorkingSet[] workingSets = new IWorkingSet[0];
-
- /**
- * A reference to a different project that the current test project will be
- * testing.
- */
- public IProject testedProject;
- /**
- * If true, this test project should be testing itself, otherwise it will be
- * testing the project pointed to by {@link #testedProject}.
- */
- public boolean testingSelf;
-
- // NOTE: These apply only to creating paired projects; when isTest is true
- // we're using
- // the normal fields above
- /**
- * If true, create a test project along with this plain project which will
- * be testing the plain project. (This flag only applies when creating
- * normal projects.)
- */
- public boolean createPairProject;
- /**
- * The application name of the test application (only applies when
- * {@link #createPairProject} is true)
- */
- public String testApplicationName;
- /**
- * True if the testing application name has been modified by the user (only
- * applies when {@link #createPairProject} is true)
- */
- public boolean testApplicationNameModified;
- /**
- * The package name of the test application (only applies when
- * {@link #createPairProject} is true)
- */
- public String testPackageName;
- /**
- * True if the testing package name has been modified by the user (only
- * applies when {@link #createPairProject} is true)
- */
- public boolean testPackageModified;
- /**
- * The project name of the test project (only applies when
- * {@link #createPairProject} is true)
- */
- public String testProjectName;
- /**
- * True if the testing project name has been modified by the user (only
- * applies when {@link #createPairProject} is true)
- */
- public boolean testProjectModified;
- /** Package name of the tested app */
- public String testTargetPackageName;
-
- /**
- * Copy project into workspace? This flag only applies when importing
- * projects (creating projects from existing source)
- */
- public boolean copyIntoWorkspace;
-
- /**
- * List of projects to be imported. Null if not importing projects.
- */
- @Nullable
- public List<ImportedProject> importProjects;
-
- /**
- * Creates a new {@link NewProjectWizardState}
- *
- * @param mode the mode to run the wizard in
- */
- public NewProjectWizardState(Mode mode) {
- this.mode = mode;
- if (mode == Mode.SAMPLE) {
- useExisting = true;
- } else if (mode == Mode.TEST) {
- createActivity = false;
- }
- }
-
- /**
- * Extract information (package name, application name, minimum SDK etc) from
- * the given Android project.
- *
- * @param path the path to the project to extract information from
- */
- public void extractFromAndroidManifest(Path path) {
- String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString();
- if (!(new File(osPath).exists())) {
- return;
- }
-
- ManifestData manifestData = AndroidManifestHelper.parseForData(osPath);
- if (manifestData == null) {
- return;
- }
-
- String newPackageName = null;
- Activity activity = null;
- String newActivityName = null;
- String minSdkVersion = null;
- try {
- newPackageName = manifestData.getPackage();
- minSdkVersion = manifestData.getMinSdkVersionString();
-
- // try to get the first launcher activity. If none, just take the first activity.
- activity = manifestData.getLauncherActivity();
- if (activity == null) {
- Activity[] activities = manifestData.getActivities();
- if (activities != null && activities.length > 0) {
- activity = activities[0];
- }
- }
- } catch (Exception e) {
- // ignore exceptions
- }
-
- if (newPackageName != null && newPackageName.length() > 0) {
- packageName = newPackageName;
- }
-
- if (activity != null) {
- newActivityName = AndroidManifest.extractActivityName(activity.getName(),
- newPackageName);
- }
-
- if (newActivityName != null && newActivityName.length() > 0) {
- activityName = newActivityName;
- // we are "importing" an existing activity, not creating a new one
- createActivity = false;
-
- // If project name and application names are empty, use the activity
- // name as a default. If the activity name has dots, it's a part of a
- // package specification and only the last identifier must be used.
- if (newActivityName.indexOf('.') != -1) {
- String[] ids = newActivityName.split(AdtConstants.RE_DOT);
- newActivityName = ids[ids.length - 1];
- }
- if (projectName == null || projectName.length() == 0 ||
- !projectNameModifiedByUser) {
- projectName = newActivityName;
- projectNameModifiedByUser = false;
- }
- if (applicationName == null || applicationName.length() == 0 ||
- !applicationNameModifiedByUser) {
- applicationNameModifiedByUser = false;
- applicationName = newActivityName;
- }
- } else {
- activityName = ""; //$NON-NLS-1$
-
- // There is no activity name to use to fill in the project and application
- // name. However if there's a package name, we can use this as a base.
- if (newPackageName != null && newPackageName.length() > 0) {
- // Package name is a java identifier, so it's most suitable for
- // an application name.
-
- if (applicationName == null || applicationName.length() == 0 ||
- !applicationNameModifiedByUser) {
- applicationName = newPackageName;
- }
-
- // For the project name, remove any dots
- newPackageName = newPackageName.replace('.', '_');
- if (projectName == null || projectName.length() == 0 ||
- !projectNameModifiedByUser) {
- projectName = newPackageName;
- }
-
- }
- }
-
- if (mode == Mode.ANY && useExisting) {
- updateSdkTargetToMatchProject(path.toFile());
- }
-
- minSdk = minSdkVersion;
- minSdkModifiedByUser = false;
- }
-
- /**
- * Try to find an SDK Target that matches the current MinSdkVersion.
- *
- * There can be multiple targets with the same sdk api version, so don't change
- * it if it's already at the right version. Otherwise pick the first target
- * that matches.
- */
- public void updateSdkTargetToMatchMinSdkVersion() {
- IAndroidTarget currentTarget = target;
- if (currentTarget != null && currentTarget.getVersion().equals(minSdk)) {
- return;
- }
-
- Sdk sdk = Sdk.getCurrent();
- if (sdk != null) {
- IAndroidTarget[] targets = sdk.getTargets();
- for (IAndroidTarget t : targets) {
- if (t.getVersion().equals(minSdk)) {
- target = t;
- return;
- }
- }
- }
- }
-
- /**
- * Updates the SDK to reflect the SDK required by the project at the given
- * location
- *
- * @param location the location of the project
- */
- public void updateSdkTargetToMatchProject(File location) {
- // Select the target matching the manifest's sdk or build properties, if any
- IAndroidTarget foundTarget = null;
- // This is the target currently in the UI
- IAndroidTarget currentTarget = target;
- String projectPath = location.getPath();
-
- // If there's a current target defined, we do not allow to change it when
- // operating in the create-from-sample mode -- since the available sample list
- // is tied to the current target, so changing it would invalidate the project we're
- // trying to load in the first place.
- if (!targetModifiedByUser) {
- ProjectProperties p = ProjectProperties.load(projectPath,
- PropertyType.PROJECT);
- if (p != null) {
- String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
- IAndroidTarget desiredTarget = Sdk.getCurrent().getTargetFromHashString(v);
- // We can change the current target if:
- // - we found a new desired target
- // - there is no current target
- // - or the current target can't run the desired target
- if (desiredTarget != null &&
- (currentTarget == null || !desiredTarget.canRunOn(currentTarget))) {
- foundTarget = desiredTarget;
- }
- }
-
- Sdk sdk = Sdk.getCurrent();
- IAndroidTarget[] targets = null;
- if (sdk != null) {
- targets = sdk.getTargets();
- }
- if (targets == null) {
- targets = new IAndroidTarget[0];
- }
-
- if (foundTarget == null && minSdk != null) {
- // Otherwise try to match the requested min-sdk-version if we find an
- // exact match, regardless of the currently selected target.
- for (IAndroidTarget existingTarget : targets) {
- if (existingTarget != null &&
- existingTarget.getVersion().equals(minSdk)) {
- foundTarget = existingTarget;
- break;
- }
- }
- }
-
- if (foundTarget == null) {
- // Or last attempt, try to match a sample project location and use it
- // if we find an exact match, regardless of the currently selected target.
- for (IAndroidTarget existingTarget : targets) {
- if (existingTarget != null &&
- projectPath.startsWith(existingTarget.getLocation())) {
- foundTarget = existingTarget;
- break;
- }
- }
- }
- }
-
- if (foundTarget != null) {
- target = foundTarget;
- }
- }
-
- /**
- * Type of project being offered/created by the wizard
- */
- public enum Mode {
- /** Create a sample project. Testing options are not presented. */
- SAMPLE,
-
- /**
- * Create a test project, either testing itself or some other project.
- * Note that even if in the {@link #ANY} mode, a test project can be
- * created as a *paired* project with the main project, so this flag
- * only means that we are creating *just* a test project
- */
- TEST,
-
- /**
- * Create an Android project, which can be a plain project, optionally
- * with a paired test project, or a sample project (the first page
- * contains toggles for choosing which
- */
- ANY;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewSampleProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewSampleProjectWizard.java
deleted file mode 100644
index 6b6a4c29e..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewSampleProjectWizard.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-
-/**
- * A "New Sample Android Project" Wizard.
- * <p/>
- * This displays the new project wizard pre-configured for samples only.
- */
-public class NewSampleProjectWizard extends NewProjectWizard {
- /**
- * Creates a new wizard for creating a sample Android project
- */
- public NewSampleProjectWizard() {
- super(Mode.SAMPLE);
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java
deleted file mode 100644
index e0959f4db..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-
-/**
- * A "New Test Android Project" Wizard.
- * <p/>
- * This is really the {@link NewProjectWizard} that only displays the "test project" pages.
- */
-public class NewTestProjectWizard extends NewProjectWizard {
- /**
- * Creates a new wizard for creating an Android Test Project
- */
- public NewTestProjectWizard() {
- super(Mode.TEST);
- }
-} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java
deleted file mode 100644
index d04ea897f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ProjectNamePage.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
-import static com.android.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
-import static com.android.ide.eclipse.adt.AdtUtils.capitalize;
-import static com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage.ACTIVITY_NAME_SUFFIX;
-import static com.android.utils.SdkUtils.stripWhitespace;
-
-import com.android.SdkConstants;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.common.xml.ManifestData.Activity;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.VersionCheck;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-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.osgi.util.TextProcessor;
-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 org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkingSet;
-
-import java.io.File;
-import java.net.URI;
-import java.util.Locale;
-
-/**
- * Initial page shown when creating projects which asks for the project name,
- * the the location of the project, working sets, etc.
- */
-public class ProjectNamePage extends WizardPage implements SelectionListener, ModifyListener {
- private final NewProjectWizardState mValues;
- /** Flag used when setting button/text state manually to ignore listener updates */
- private boolean mIgnore;
- /** Last user-browsed location, static so that it be remembered for the whole session */
- private static String sCustomLocationOsPath = ""; //$NON-NLS-1$
- private static boolean sAutoComputeCustomLocation = true;
-
- private Text mProjectNameText;
- private Text mLocationText;
- private Button mCreateSampleRadioButton;
- private Button mCreateNewButton;
- private Button mUseDefaultCheckBox;
- private Button mBrowseButton;
- private Label mLocationLabel;
- private WorkingSetGroup mWorkingSetGroup;
- /**
- * Whether we've made sure the Tools are up to date (enough that all the
- * resources required by the New Project wizard are present -- we don't
- * necessarily check for newer versions than that here; that's done by
- * {@link VersionCheck}, though that check doesn't <b>enforce</b> an update
- * since it needs to allow the user to proceed to access the SDK manager
- * etc.)
- */
- private boolean mCheckedSdkUptodate;
-
- /**
- * Create the wizard.
- * @param values current wizard state
- */
- ProjectNamePage(NewProjectWizardState values) {
- super("projectNamePage"); //$NON-NLS-1$
- mValues = values;
-
- setTitle("Create Android Project");
- setDescription("Select project name and type of project");
- mWorkingSetGroup = new WorkingSetGroup();
- setWorkingSets(new IWorkingSet[0]);
- }
-
- void init(IStructuredSelection selection, IWorkbenchPart activePart) {
- setWorkingSets(WorkingSetHelper.getSelectedWorkingSet(selection, activePart));
- }
-
- /**
- * Create contents of the wizard.
- * @param parent the parent to add the page to
- */
- @Override
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
- container.setLayout(new GridLayout(3, false));
-
- Label nameLabel = new Label(container, SWT.NONE);
- nameLabel.setText("Project Name:");
-
- mProjectNameText = new Text(container, SWT.BORDER);
- mProjectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
- mProjectNameText.addModifyListener(this);
-
- if (mValues.mode != Mode.TEST) {
- mCreateNewButton = new Button(container, SWT.RADIO);
- mCreateNewButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
- mCreateNewButton.setText("Create new project in workspace");
- mCreateNewButton.addSelectionListener(this);
-
- // TBD: Should we hide this completely, and make samples something you only invoke
- // from the "New Sample Project" wizard?
- mCreateSampleRadioButton = new Button(container, SWT.RADIO);
- mCreateSampleRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false,
- 3, 1));
- mCreateSampleRadioButton.setText("Create project from existing sample");
- mCreateSampleRadioButton.addSelectionListener(this);
- }
-
- Label separator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
- separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
-
- mUseDefaultCheckBox = new Button(container, SWT.CHECK);
- mUseDefaultCheckBox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
- mUseDefaultCheckBox.setText("Use default location");
- mUseDefaultCheckBox.addSelectionListener(this);
-
- mLocationLabel = new Label(container, SWT.NONE);
- mLocationLabel.setText("Location:");
-
- mLocationText = new Text(container, SWT.BORDER);
- mLocationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mLocationText.addModifyListener(this);
-
- mBrowseButton = new Button(container, SWT.NONE);
- mBrowseButton.setText("Browse...");
- mBrowseButton.addSelectionListener(this);
-
- Composite group = mWorkingSetGroup.createControl(container);
- group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));
-
- setControl(container);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
-
- if (visible) {
- try {
- mIgnore = true;
- if (mValues.projectName != null) {
- mProjectNameText.setText(mValues.projectName);
- mProjectNameText.setFocus();
- }
- if (mValues.mode == Mode.ANY || mValues.mode == Mode.TEST) {
- if (mValues.useExisting) {
- assert false; // This is now handled by the separate import wizard
- } else if (mCreateNewButton != null) {
- mCreateNewButton.setSelection(true);
- }
- } else if (mValues.mode == Mode.SAMPLE) {
- mCreateSampleRadioButton.setSelection(true);
- }
- if (mValues.projectLocation != null) {
- mLocationText.setText(mValues.projectLocation.getPath());
- }
- mUseDefaultCheckBox.setSelection(mValues.useDefaultLocation);
- updateLocationState();
- } finally {
- mIgnore = false;
- }
- }
-
- validatePage();
- }
-
- @Override
- public void modifyText(ModifyEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
-
- if (source == mProjectNameText) {
- onProjectFieldModified();
- if (!mValues.useDefaultLocation && !mValues.projectLocationModifiedByUser) {
- updateLocationPathField(null);
- }
- } else if (source == mLocationText) {
- mValues.projectLocationModifiedByUser = true;
- if (!mValues.useDefaultLocation) {
- File f = new File(mLocationText.getText().trim());
- mValues.projectLocation = f;
- if (f.exists() && f.isDirectory() && !f.equals(mValues.projectLocation)) {
- updateLocationPathField(mValues.projectLocation.getPath());
- }
- }
- }
-
- validatePage();
- }
-
- private void onProjectFieldModified() {
- mValues.projectName = mProjectNameText.getText().trim();
- mValues.projectNameModifiedByUser = true;
-
- if (!mValues.applicationNameModifiedByUser) {
- mValues.applicationName = capitalize(mValues.projectName);
- if (!mValues.testApplicationNameModified) {
- mValues.testApplicationName =
- ApplicationInfoPage.suggestTestApplicationName(mValues.applicationName);
- }
- }
- if (!mValues.activityNameModifiedByUser) {
- String name = capitalize(mValues.projectName);
- mValues.activityName = stripWhitespace(name) + ACTIVITY_NAME_SUFFIX;
- }
- if (!mValues.testProjectModified) {
- mValues.testProjectName =
- ApplicationInfoPage.suggestTestProjectName(mValues.projectName);
- }
- if (!mValues.projectLocationModifiedByUser) {
- updateLocationPathField(null);
- }
- }
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
-
- if (source == mCreateNewButton && mCreateNewButton != null
- && mCreateNewButton.getSelection()) {
- mValues.useExisting = false;
- if (mValues.mode == Mode.SAMPLE) {
- // Only reset the mode if we're toggling from sample back to create new
- // or create existing. We can only come to the sample state when we're in
- // ANY mode. (In particular, we don't want to switch to ANY if you're
- // in test mode.
- mValues.mode = Mode.ANY;
- }
- updateLocationState();
- } else if (source == mCreateSampleRadioButton && mCreateSampleRadioButton.getSelection()) {
- mValues.useExisting = true;
- mValues.useDefaultLocation = true;
- if (!mUseDefaultCheckBox.getSelection()) {
- try {
- mIgnore = true;
- mUseDefaultCheckBox.setSelection(true);
- } finally {
- mIgnore = false;
- }
- }
- mValues.mode = Mode.SAMPLE;
- updateLocationState();
- } else if (source == mUseDefaultCheckBox) {
- mValues.useDefaultLocation = mUseDefaultCheckBox.getSelection();
- updateLocationState();
- } else if (source == mBrowseButton) {
- onOpenDirectoryBrowser();
- }
-
- validatePage();
- }
-
- /**
- * Enables or disable the location widgets depending on the user selection:
- * the location path is enabled when using the "existing source" mode (i.e. not new project)
- * or in new project mode with the "use default location" turned off.
- */
- private void updateLocationState() {
- boolean isNewProject = !mValues.useExisting;
- boolean isCreateFromSample = mValues.mode == Mode.SAMPLE;
- boolean useDefault = mValues.useDefaultLocation && !isCreateFromSample;
- boolean locationEnabled = (!isNewProject || !useDefault) && !isCreateFromSample;
-
- mUseDefaultCheckBox.setEnabled(isNewProject);
- mLocationLabel.setEnabled(locationEnabled);
- mLocationText.setEnabled(locationEnabled);
- mBrowseButton.setEnabled(locationEnabled);
-
- updateLocationPathField(null);
- }
-
- /**
- * Display a directory browser and update the location path field with the selected path
- */
- private void onOpenDirectoryBrowser() {
-
- String existingDir = mLocationText.getText().trim();
-
- // Disable the path if it doesn't exist
- if (existingDir.length() == 0) {
- existingDir = null;
- } else {
- File f = new File(existingDir);
- if (!f.exists()) {
- existingDir = null;
- }
- }
-
- DirectoryDialog directoryDialog = new DirectoryDialog(mLocationText.getShell());
- directoryDialog.setMessage("Browse for folder");
- directoryDialog.setFilterPath(existingDir);
- String dir = directoryDialog.open();
-
- if (dir != null) {
- updateLocationPathField(dir);
- validatePage();
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- /**
- * 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);
- }
-
- /**
- * Updates the location directory path field.
- * <br/>
- * When custom user selection is enabled, use the absDir argument if not null and also
- * save it internally. If absDir is null, restore the last saved absDir. This allows the
- * user selection to be remembered when the user switches from default to custom.
- * <br/>
- * When custom user selection is disabled, use the workspace default location with the
- * current project name. This does not change the internally cached absDir.
- *
- * @param absDir A new absolute directory path or null to use the default.
- */
- private void updateLocationPathField(String absDir) {
- boolean isNewProject = !mValues.useExisting || mValues.mode == Mode.SAMPLE;
- boolean useDefault = mValues.useDefaultLocation;
- boolean customLocation = !isNewProject || !useDefault;
-
- if (!mIgnore) {
- try {
- mIgnore = true;
- if (customLocation) {
- if (absDir != null) {
- // We get here if the user selected a directory with the "Browse" button.
- // Disable auto-compute of the custom location unless the user selected
- // the exact same path.
- sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
- absDir.equals(sCustomLocationOsPath);
- sCustomLocationOsPath = TextProcessor.process(absDir);
- } else if (sAutoComputeCustomLocation ||
- (!isNewProject && !new File(sCustomLocationOsPath).isDirectory())) {
- // As a default import location, just suggest the home directory; the user
- // needs to point to a project to import.
- // TODO: Open file chooser automatically?
- sCustomLocationOsPath = System.getProperty("user.home"); //$NON-NLS-1$
- }
- if (!mLocationText.getText().equals(sCustomLocationOsPath)) {
- mLocationText.setText(sCustomLocationOsPath);
- mValues.projectLocation = new File(sCustomLocationOsPath);
- }
- } else {
- String value = Platform.getLocation().append(mValues.projectName).toString();
- value = TextProcessor.process(value);
- if (!mLocationText.getText().equals(value)) {
- mLocationText.setText(value);
- mValues.projectLocation = new File(value);
- }
- }
- } finally {
- mIgnore = false;
- }
- }
-
- if (mValues.useExisting && mValues.projectLocation != null
- && mValues.projectLocation.exists() && mValues.mode != Mode.SAMPLE) {
- mValues.extractFromAndroidManifest(new Path(mValues.projectLocation.getPath()));
- if (!mValues.projectNameModifiedByUser && mValues.projectName != null) {
- try {
- mIgnore = true;
- mProjectNameText.setText(mValues.projectName);
- } finally {
- mIgnore = false;
- }
- }
- }
- }
-
- private void validatePage() {
- IStatus status = null;
-
- // Validate project name -- unless we're creating a sample, in which case
- // the user will get a chance to pick the name on the Sample page
- if (mValues.mode != Mode.SAMPLE) {
- status = validateProjectName(mValues.projectName);
- }
-
- if (status == null || status.getSeverity() != IStatus.ERROR) {
- IStatus validLocation = validateLocation();
- if (validLocation != null) {
- status = validLocation;
- }
- }
-
- if (!mCheckedSdkUptodate) {
- // Ensure that we have a recent enough version of the Tools that the right templates
- // are available
- File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER
- + File.separator + FN_PROJECT_PROGUARD_FILE);
- if (!file.exists()) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("You do not have the latest version of the "
- + "SDK Tools installed: Please update. (Missing %1$s)", file.getPath()));
- } else {
- mCheckedSdkUptodate = true;
- }
- }
-
- // -- update UI & enable finish if there's no error
- 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 validateLocation() {
- if (mValues.mode == Mode.SAMPLE) {
- // Samples are always created in the default directory
- return null;
- }
-
- // Validate location
- Path path = new Path(mValues.projectLocation.getPath());
- if (!mValues.useExisting) {
- if (!mValues.useDefaultLocation) {
- // If not using the default value validate the location.
- URI uri = URIUtil.toURI(path.toOSString());
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IProject handle = workspace.getRoot().getProject(mValues.projectName);
- IStatus locationStatus = workspace.validateProjectLocationURI(handle, uri);
- if (!locationStatus.isOK()) {
- return locationStatus;
- }
- // The location is valid as far as Eclipse is concerned (i.e. mostly not
- // an existing workspace project.) Check it either doesn't exist or is
- // a directory that is empty.
- File f = path.toFile();
- if (f.exists() && !f.isDirectory()) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "A directory name must be specified.");
- } else if (f.isDirectory()) {
- // However if the directory exists, we should put a
- // warning if it is not empty. We don't put an error
- // (we'll ask the user again for confirmation before
- // using the directory.)
- String[] l = f.list();
- if (l != null && l.length != 0) {
- return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
- "The selected output directory is not empty.");
- }
- }
- } else {
- // Otherwise validate the path string is not empty
- if (mValues.projectLocation.getPath().length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "A directory name must be specified.");
- }
- File dest = path.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.",
- mValues.projectName));
- }
- }
- } else {
- // Must be an existing directory
- File f = path.toFile();
- if (!f.isDirectory()) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "An existing directory name must be specified.");
- }
-
- // Check there's an android manifest in the directory
- String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString();
- File manifestFile = new File(osPath);
- if (!manifestFile.isFile()) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format(
- "Choose a valid Android code directory\n" +
- "(%1$s not found in %2$s.)",
- SdkConstants.FN_ANDROID_MANIFEST_XML, f.getName()));
- }
-
- // Parse it and check the important fields.
- ManifestData manifestData = AndroidManifestHelper.parseForData(osPath);
- if (manifestData == null) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("File %1$s could not be parsed.", osPath));
- }
- String packageName = manifestData.getPackage();
- if (packageName == null || packageName.length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("No package name defined in %1$s.", osPath));
- }
- Activity[] activities = manifestData.getActivities();
- if (activities == null || activities.length == 0) {
- // This is acceptable now as long as no activity needs to be
- // created
- if (mValues.createActivity) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("No activity name defined in %1$s.", osPath));
- }
- }
-
- // If there's already a .project, tell the user to use import instead.
- if (path.append(".project").toFile().exists()) { //$NON-NLS-1$
- return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
- "An Eclipse project already exists in this directory.\n" +
- "Consider using File > Import > Existing Project instead.");
- }
- }
-
- return null;
- }
-
- public static IStatus validateProjectName(String projectName) {
- if (projectName == null || projectName.length() == 0) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "Project name must be specified");
- } else {
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT);
- if (!nameStatus.isOK()) {
- return nameStatus;
- } else {
- // Note: the case-sensitiveness of the project name matters and can cause a
- // conflict *later* when creating the project resource, so let's check it now.
- for (IProject existingProj : workspace.getRoot().getProjects()) {
- if (projectName.equalsIgnoreCase(existingProj.getName())) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "A project with that name already exists in the workspace");
- }
- }
- }
- }
-
- return null;
- }
-
- @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();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SampleSelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SampleSelectionPage.java
deleted file mode 100644
index 197247083..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SampleSelectionPage.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-import com.android.sdklib.IAndroidTarget;
-import com.android.utils.Pair;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-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.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/** Page where the user can select a sample to "instantiate" */
-class SampleSelectionPage extends WizardPage implements SelectionListener, ModifyListener {
- private final NewProjectWizardState mValues;
- private boolean mIgnore;
-
- private Table mTable;
- private TableViewer mTableViewer;
- private IAndroidTarget mCurrentSamplesTarget;
- private Text mSampleProjectName;
-
- /**
- * Create the wizard.
- */
- SampleSelectionPage(NewProjectWizardState values) {
- super("samplePage"); //$NON-NLS-1$
- setTitle("Select Sample");
- setDescription("Select which sample to create");
- mValues = values;
- }
-
- /**
- * Create contents of the wizard.
- */
- @Override
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
- container.setLayout(new GridLayout(2, false));
-
- mTableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
- mTable = mTableViewer.getTable();
- GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
- gridData.heightHint = 300;
- mTable.setLayoutData(gridData);
- mTable.addSelectionListener(this);
-
- setControl(container);
-
- Label projectLabel = new Label(container, SWT.NONE);
- projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- projectLabel.setText("Project Name:");
-
- mSampleProjectName = new Text(container, SWT.BORDER);
- mSampleProjectName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- mSampleProjectName.addModifyListener(this);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
-
- if (visible) {
- if (mValues.projectName != null) {
- try {
- mIgnore = true;
- mSampleProjectName.setText(mValues.projectName);
- } finally {
- mIgnore = false;
- }
- }
-
- // Update samples list if the SDK target has changed (or if it hasn't yet
- // been populated)
- if (mCurrentSamplesTarget != mValues.target) {
- mCurrentSamplesTarget = mValues.target;
- updateSamples();
- }
-
- validatePage();
- }
- }
-
- private void updateSamples() {
- IBaseLabelProvider labelProvider = new ColumnLabelProvider() {
- @Override
- public Image getImage(Object element) {
- return AdtPlugin.getAndroidLogo();
- }
-
- @Override
- public String getText(Object element) {
- if (element instanceof Pair<?, ?>) {
- Object name = ((Pair<?, ?>) element).getFirst();
- return name.toString();
- }
- return element.toString(); // Fallback. Should not happen.
- }
- };
-
- mTableViewer.setContentProvider(new ArrayContentProvider());
- mTableViewer.setLabelProvider(labelProvider);
-
- if (mValues.samples != null && mValues.samples.size() > 0) {
- Object[] samples = mValues.samples.toArray();
- mTableViewer.setInput(samples);
-
- mTable.select(0);
- selectSample(mValues.samples.get(0).getSecond());
- extractNamesFromAndroidManifest();
- }
- }
-
- private void selectSample(File sample) {
- mValues.chosenSample = sample;
- if (sample != null && !mValues.projectNameModifiedByUser) {
- mValues.projectName = sample.getName();
- if (SdkConstants.FD_SAMPLE.equals(mValues.projectName) &&
- sample.getParentFile() != null) {
- mValues.projectName = sample.getParentFile().getName() + '_' + mValues.projectName;
- }
- try {
- mIgnore = true;
- mSampleProjectName.setText(mValues.projectName);
- } finally {
- mIgnore = false;
- }
- updatedProjectName();
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- if (e.getSource() == mTable) {
- extractNamesFromAndroidManifest();
- int index = mTable.getSelectionIndex();
- if (index >= 0) {
- Object[] roots = (Object[]) mTableViewer.getInput();
- selectSample(((Pair<String, File>) roots[index]).getSecond());
- } else {
- selectSample(null);
- }
- } else {
- assert false : e.getSource();
- }
-
- validatePage();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- @Override
- public void modifyText(ModifyEvent e) {
- if (mIgnore) {
- return;
- }
-
- if (e.getSource() == mSampleProjectName) {
- mValues.projectName = mSampleProjectName.getText().trim();
- mValues.projectNameModifiedByUser = true;
- updatedProjectName();
- }
-
- validatePage();
- }
-
- private void updatedProjectName() {
- if (mValues.useDefaultLocation) {
- mValues.projectLocation = Platform.getLocation().toFile();
- }
- }
-
- /**
- * A sample was selected. Update the location field, manifest and validate.
- * Extract names from an android manifest.
- * This is done only if the user selected the "use existing source" and a manifest xml file
- * can actually be found in the custom user directory.
- */
- private void extractNamesFromAndroidManifest() {
- if (mValues.chosenSample == null || !mValues.chosenSample.isDirectory()) {
- return;
- }
-
- Path path = new Path(mValues.chosenSample.getPath());
- mValues.extractFromAndroidManifest(path);
- }
-
- @Override
- public boolean isPageComplete() {
- if (mValues.mode != Mode.SAMPLE) {
- return true;
- }
-
- // Ensure that when creating samples, the Finish button isn't enabled until
- // the user has reached and completed this page
- if (mValues.chosenSample == null) {
- return false;
- }
-
- return super.isPageComplete();
- }
-
- private void validatePage() {
- IStatus status = null;
- if (mValues.samples == null || mValues.samples.size() == 0) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- "The chosen SDK does not contain any samples");
- } else if (mValues.chosenSample == null) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "Choose a sample");
- } else if (!mValues.chosenSample.exists()) {
- status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- String.format("Sample does not exist: %1$s", mValues.chosenSample.getPath()));
- } else {
- status = ProjectNamePage.validateProjectName(mValues.projectName);
- }
-
- // -- update UI & enable finish if there's no error
- 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);
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SdkSelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SdkSelectionPage.java
deleted file mode 100644
index 6cafcf057..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/SdkSelectionPage.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.SdkConstants;
-import com.android.annotations.Nullable;
-import com.android.ide.common.sdk.LoadStatus;
-import com.android.ide.common.xml.AndroidManifestParser;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
-import com.android.io.FileWrapper;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkManager;
-import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
-import com.android.utils.NullLogger;
-import com.android.utils.Pair;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Pattern;
-
-/** A page in the New Project wizard where you select the target SDK */
-class SdkSelectionPage extends WizardPage implements ITargetChangeListener {
- private final NewProjectWizardState mValues;
- private boolean mIgnore;
- private SdkTargetSelector mSdkTargetSelector;
-
- /**
- * Create the wizard.
- */
- SdkSelectionPage(NewProjectWizardState values) {
- super("sdkSelection"); //$NON-NLS-1$
- mValues = values;
-
- setTitle("Select Build Target");
- AdtPlugin.getDefault().addTargetListener(this);
- }
-
- @Override
- public void dispose() {
- AdtPlugin.getDefault().removeTargetListener(this);
- super.dispose();
- }
-
- /**
- * Create contents of the wizard.
- */
- @Override
- public void createControl(Composite parent) {
- Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
- // Layout has 1 column
- group.setLayout(new GridLayout());
- group.setLayoutData(new GridData(GridData.FILL_BOTH));
- group.setFont(parent.getFont());
- group.setText("Build Target");
-
- // The selector is created without targets. They are added below in the change listener.
- mSdkTargetSelector = new SdkTargetSelector(group, null);
-
- mSdkTargetSelector.setSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- mValues.target = mSdkTargetSelector.getSelected();
- mValues.targetModifiedByUser = true;
- onSdkTargetModified();
- validatePage();
- }
- });
-
- onSdkLoaded();
-
- setControl(group);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (mValues.mode == Mode.SAMPLE) {
- setDescription("Choose an SDK to select a sample from");
- } else {
- setDescription("Choose an SDK to target");
- }
- try {
- mIgnore = true;
- if (mValues.target != null) {
- mSdkTargetSelector.setSelection(mValues.target);
- }
- } finally {
- mIgnore = false;
- }
-
- validatePage();
- }
-
- @Override
- public boolean isPageComplete() {
- // Ensure that the Finish button isn't enabled until
- // the user has reached and completed this page
- if (mValues.target == null) {
- return false;
- }
-
- return super.isPageComplete();
- }
-
- /**
- * Called when an SDK target is modified.
- *
- * Also changes the minSdkVersion field to reflect the sdk api level that has
- * just been selected.
- */
- private void onSdkTargetModified() {
- if (mIgnore) {
- return;
- }
-
- IAndroidTarget target = mValues.target;
-
- // Update the minimum SDK text field?
- // We do if one of two conditions are met:
- if (target != null) {
- boolean setMinSdk = false;
- AndroidVersion version = target.getVersion();
- int apiLevel = version.getApiLevel();
- // 1. Has the user not manually edited the SDK field yet? If so, keep
- // updating it to the selected value.
- if (!mValues.minSdkModifiedByUser) {
- setMinSdk = true;
- } else {
- // 2. Is the API level set to a higher level than the newly selected
- // target SDK? If so, change it down to the new lower value.
- String s = mValues.minSdk;
- if (s.length() > 0) {
- try {
- int currentApi = Integer.parseInt(s);
- if (currentApi > apiLevel) {
- setMinSdk = true;
- }
- } catch (NumberFormatException nfe) {
- // User may have typed something invalid -- ignore
- }
- }
- }
- if (setMinSdk) {
- String minSdk;
- if (version.isPreview()) {
- minSdk = version.getCodename();
- } else {
- minSdk = Integer.toString(apiLevel);
- }
- mValues.minSdk = minSdk;
- }
- }
-
- loadSamplesForTarget(target);
- }
-
- /**
- * Updates the list of all samples for the given target SDK.
- * The list is stored in mSamplesPaths as absolute directory paths.
- * The combo is recreated to match this.
- */
- private void loadSamplesForTarget(IAndroidTarget target) {
- // Keep the name of the old selection (if there were any samples)
- File previouslyChosenSample = mValues.chosenSample;
-
- mValues.samples.clear();
- mValues.chosenSample = null;
-
- if (target != null) {
- // Get the sample root path and recompute the list of samples
- String samplesRootPath = target.getPath(IAndroidTarget.SAMPLES);
-
- File root = new File(samplesRootPath);
- findSamplesManifests(root, root, null, null, mValues.samples);
-
- Sdk sdk = Sdk.getCurrent();
- if (sdk != null) {
- // Parse the extras to see if we can find samples that are
- // compatible with the selected target API.
- // First we need an SdkManager that suppresses all output.
- SdkManager sdkman = sdk.getNewSdkManager(NullLogger.getLogger());
-
- Map<File, String> extras = sdkman.getExtraSamples();
- for (Entry<File, String> entry : extras.entrySet()) {
- File path = entry.getKey();
- String name = entry.getValue();
-
- // Case where the sample is at the root of the directory and not
- // in a per-sample sub-directory.
- if (path.getName().equals(SdkConstants.FD_SAMPLE)) {
- findSampleManifestInDir(
- path, path, name, target.getVersion(), mValues.samples);
- }
-
- // Scan sub-directories
- findSamplesManifests(
- path, path, name, target.getVersion(), mValues.samples);
- }
- }
-
- if (mValues.samples.isEmpty()) {
- return;
- } else {
- Collections.sort(mValues.samples, new Comparator<Pair<String, File>>() {
- @Override
- public int compare(Pair<String, File> o1, Pair<String, File> o2) {
- // Compare the display name of the sample
- return o1.getFirst().compareTo(o2.getFirst());
- }
- });
- }
-
- // Try to find the old selection.
- if (previouslyChosenSample != null) {
- String previouslyChosenName = previouslyChosenSample.getName();
- for (int i = 0, n = mValues.samples.size(); i < n; i++) {
- File file = mValues.samples.get(i).getSecond();
- if (file.getName().equals(previouslyChosenName)) {
- mValues.chosenSample = file;
- break;
- }
- }
- }
- }
- }
-
- /**
- * Recursively find potential sample directories under the given directory.
- * Actually lists any directory that contains an android manifest.
- * Paths found are added the samplesPaths list.
- *
- * @param rootDir The "samples" root directory. Doesn't change during recursion.
- * @param currDir The directory being scanned. Caller must initially set it to {@code rootDir}.
- * @param extraName Optional name appended to the samples display name. Typically used to
- * indicate a sample comes from a given extra package.
- * @param targetVersion Optional target version filter. If non null, only samples that are
- * compatible with the given target will be listed.
- * @param samplesPaths A non-null list filled by this method with all samples found. The
- * pair is (String: sample display name => File: sample directory).
- */
- private void findSamplesManifests(
- File rootDir,
- File currDir,
- @Nullable String extraName,
- @Nullable AndroidVersion targetVersion,
- List<Pair<String, File>> samplesPaths) {
- if (!currDir.isDirectory()) {
- return;
- }
-
- for (File f : currDir.listFiles()) {
- if (f.isDirectory()) {
- findSampleManifestInDir(f, rootDir, extraName, targetVersion, samplesPaths);
-
- // Recurse in the project, to find embedded tests sub-projects
- // We can however skip this recursion for known android sub-dirs that
- // can't have projects, namely for sources, assets and resources.
- String leaf = f.getName();
- if (!SdkConstants.FD_SOURCES.equals(leaf) &&
- !SdkConstants.FD_ASSETS.equals(leaf) &&
- !SdkConstants.FD_RES.equals(leaf)) {
- findSamplesManifests(rootDir, f, extraName, targetVersion, samplesPaths);
- }
- }
- }
- }
-
- private void findSampleManifestInDir(
- File sampleDir,
- File rootDir,
- String extraName,
- AndroidVersion targetVersion,
- List<Pair<String, File>> samplesPaths) {
- // Assume this is a sample if it contains an android manifest.
- File manifestFile = new File(sampleDir, SdkConstants.FN_ANDROID_MANIFEST_XML);
- if (manifestFile.isFile()) {
- try {
- ManifestData data =
- AndroidManifestParser.parse(new FileWrapper(manifestFile));
- if (data != null) {
- boolean accept = false;
- if (targetVersion == null) {
- accept = true;
- } else if (targetVersion != null) {
- int i = data.getMinSdkVersion();
- if (i != ManifestData.MIN_SDK_CODENAME) {
- accept = i <= targetVersion.getApiLevel();
- } else {
- String s = data.getMinSdkVersionString();
- if (s != null) {
- accept = s.equals(targetVersion.getCodename());
- }
- }
- }
-
- if (accept) {
- String name = getSampleDisplayName(extraName, rootDir, sampleDir);
- samplesPaths.add(Pair.of(name, sampleDir));
- }
- }
- } catch (Exception e) {
- // Ignore. Don't use a sample which manifest doesn't parse correctly.
- AdtPlugin.log(IStatus.INFO,
- "NPW ignoring malformed manifest %s", //$NON-NLS-1$
- manifestFile.getAbsolutePath());
- }
- }
- }
-
- /**
- * Compute the sample name compared to its root directory.
- */
- private String getSampleDisplayName(String extraName, File rootDir, File sampleDir) {
- String name = null;
- if (!rootDir.equals(sampleDir)) {
- String path = sampleDir.getPath();
- int n = rootDir.getPath().length();
- if (path.length() > n) {
- path = path.substring(n);
- if (path.charAt(0) == File.separatorChar) {
- path = path.substring(1);
- }
- if (path.endsWith(File.separator)) {
- path = path.substring(0, path.length() - 1);
- }
- name = path.replaceAll(Pattern.quote(File.separator), " > "); //$NON-NLS-1$
- }
- }
- if (name == null &&
- rootDir.equals(sampleDir) &&
- sampleDir.getName().equals(SdkConstants.FD_SAMPLE) &&
- extraName != null) {
- // This is an old-style extra with one single sample directory. Just use the
- // extra's name as the same name.
- return extraName;
- }
- if (name == null) {
- // Otherwise try to use the sample's directory name as the sample name.
- while (sampleDir != null &&
- (name == null ||
- SdkConstants.FD_SAMPLE.equals(name) ||
- SdkConstants.FD_SAMPLES.equals(name))) {
- name = sampleDir.getName();
- sampleDir = sampleDir.getParentFile();
- }
- }
- if (name == null) {
- if (extraName != null) {
- // In the unlikely case nothing worked and we have an extra name, use that.
- return extraName;
- } else {
- name = "Sample"; // fallback name... should not happen. //$NON-NLS-1$
- }
- }
- if (extraName != null) {
- name = name + " [" + extraName + ']'; //$NON-NLS-1$
- }
-
- return name;
- }
-
- private void validatePage() {
- String error = null;
-
- if (AdtPlugin.getDefault().getSdkLoadStatus() == LoadStatus.LOADING) {
- error = "The SDK is still loading; please wait.";
- }
-
- if (error == null && mValues.target == null) {
- error = "An SDK Target must be specified.";
- }
-
- if (error == null && mValues.mode == Mode.SAMPLE) {
- // Make sure this SDK target contains samples
- if (mValues.samples == null || mValues.samples.size() == 0) {
- error = "This target has no samples. Please select another target.";
- }
- }
-
- // -- update UI & enable finish if there's no error
- setPageComplete(error == null);
- if (error != null) {
- setMessage(error, IMessageProvider.ERROR);
- } else {
- setErrorMessage(null);
- setMessage(null);
- }
- }
-
- // ---- Implements ITargetChangeListener ----
- @Override
- public void onSdkLoaded() {
- if (mSdkTargetSelector == null) {
- return;
- }
-
- // Update the sdk target selector with the new targets
-
- // get the targets from the sdk
- IAndroidTarget[] targets = null;
- if (Sdk.getCurrent() != null) {
- targets = Sdk.getCurrent().getTargets();
- }
- mSdkTargetSelector.setTargets(targets);
-
- // If there's only one target, select it.
- // This will invoke the selection listener on the selector defined above.
- if (targets != null && targets.length == 1) {
- mValues.target = targets[0];
- mSdkTargetSelector.setSelection(mValues.target);
- onSdkTargetModified();
- } else if (targets != null) {
- // Pick the highest available platform by default (see issue #17505
- // for related discussion.)
- IAndroidTarget initialTarget = null;
- for (IAndroidTarget target : targets) {
- if (target.isPlatform()
- && !target.getVersion().isPreview()
- && (initialTarget == null ||
- target.getVersion().getApiLevel() >
- initialTarget.getVersion().getApiLevel())) {
- initialTarget = target;
- }
- }
- if (initialTarget != null) {
- mValues.target = initialTarget;
- try {
- mIgnore = true;
- mSdkTargetSelector.setSelection(mValues.target);
- } finally {
- mIgnore = false;
- }
- onSdkTargetModified();
- }
- }
-
- validatePage();
- }
-
- @Override
- public void onProjectTargetChange(IProject changedProject) {
- // Ignore
- }
-
- @Override
- public void onTargetLoaded(IAndroidTarget target) {
- // Ignore
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/TestTargetPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/TestTargetPage.java
deleted file mode 100644
index f1c188ae9..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/TestTargetPage.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2011 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.newproject;
-
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.ui.JavaElementLabelProvider;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.ILabelProvider;
-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.ui.dialogs.FilteredList;
-
-/**
- * Page shown when creating a test project which lets you choose between testing
- * yourself and testing a different project
- */
-class TestTargetPage extends WizardPage implements SelectionListener {
- private final NewProjectWizardState mValues;
- /** Flag used when setting button/text state manually to ignore listener updates */
- private boolean mIgnore;
- private String mLastExistingPackageName;
-
- private Button mCurrentRadioButton;
- private Button mExistingRadioButton;
- private FilteredList mProjectList;
- private boolean mPageShown;
-
- /**
- * Create the wizard.
- */
- TestTargetPage(NewProjectWizardState values) {
- super("testTargetPage"); //$NON-NLS-1$
- setTitle("Select Test Target");
- setDescription("Choose a project to test");
- mValues = values;
- }
-
- /**
- * Create contents of the wizard.
- */
- @Override
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
-
- setControl(container);
- container.setLayout(new GridLayout(2, false));
-
- mCurrentRadioButton = new Button(container, SWT.RADIO);
- mCurrentRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
- mCurrentRadioButton.setText("This project");
- mCurrentRadioButton.addSelectionListener(this);
-
- mExistingRadioButton = new Button(container, SWT.RADIO);
- mExistingRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
- mExistingRadioButton.setText("An existing Android project:");
- mExistingRadioButton.addSelectionListener(this);
-
- ILabelProvider labelProvider = new JavaElementLabelProvider(
- JavaElementLabelProvider.SHOW_DEFAULT);
- mProjectList = new FilteredList(container,
- SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE, labelProvider,
- true /*ignoreCase*/, false /*allowDuplicates*/, true /* matchEmptyString*/);
- mProjectList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
- mProjectList.addSelectionListener(this);
- }
-
- private void initializeList() {
- ProjectChooserHelper helper = new ProjectChooserHelper(getShell(), null /*filter*/);
- IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
- IJavaModel javaModel = JavaCore.create(workspaceRoot);
- IJavaProject[] androidProjects = helper.getAndroidProjects(javaModel);
- mProjectList.setElements(androidProjects);
- if (mValues.testedProject != null) {
- for (IJavaProject project : androidProjects) {
- if (project.getProject() == mValues.testedProject) {
- mProjectList.setSelection(new Object[] { project });
- break;
- }
- }
- } else {
- // No initial selection: force the user to choose
- mProjectList.setSelection(new int[0]);
- }
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- mPageShown = true;
-
- if (visible) {
- try {
- mIgnore = true;
- mCurrentRadioButton.setSelection(mValues.testingSelf);
- mExistingRadioButton.setSelection(!mValues.testingSelf);
- mProjectList.setEnabled(!mValues.testingSelf);
-
- if (mProjectList.isEmpty()) {
- initializeList();
- }
- if (!mValues.testingSelf) {
- mProjectList.setFocus();
- IProject project = getSelectedProject();
- if (project != null) {
- // The FilteredList seems to -insist- on selecting the first item
- // in the list, even when the selection is explicitly set to an empty
- // array. This means the user is looking at a selection, so we need
- // to also go ahead and select this item in the model such that the
- // two agree, even if we would have preferred to have no initial
- // selection.
- mValues.testedProject = project;
- }
- }
- } finally {
- mIgnore = false;
- }
- }
-
- validatePage();
- }
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
- if (source == mExistingRadioButton) {
- mProjectList.setEnabled(true);
- mValues.testingSelf = false;
- setExistingProject(getSelectedProject());
- mProjectList.setFocus();
- } else if (source == mCurrentRadioButton) {
- mProjectList.setEnabled(false);
- mValues.testingSelf = true;
- mValues.testedProject = null;
- } else {
- // The event must be from the project list, which unfortunately doesn't
- // pass itself as the selection event, it passes a reference to some internal
- // table widget that it uses, so we check for this case last
- IProject project = getSelectedProject();
- if (project != mValues.testedProject) {
- setExistingProject(project);
- }
- }
-
- validatePage();
- }
-
- private IProject getSelectedProject() {
- Object[] selection = mProjectList.getSelection();
- IProject project = selection != null && selection.length == 1
- ? ((IJavaProject) selection[0]).getProject() : null;
- return project;
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- private void setExistingProject(IProject project) {
- mValues.testedProject = project;
-
- // Try to update the application, package, sdk target and minSdkVersion accordingly
- if (project != null &&
- (!mValues.applicationNameModifiedByUser ||
- !mValues.packageNameModifiedByUser ||
- !mValues.targetModifiedByUser ||
- !mValues.minSdkModifiedByUser)) {
- ManifestData manifestData = AndroidManifestHelper.parseForData(project);
- if (manifestData != null) {
- String appName = String.format("%1$sTest", project.getName());
- String packageName = manifestData.getPackage();
- String minSdkVersion = manifestData.getMinSdkVersionString();
- IAndroidTarget sdkTarget = null;
- if (Sdk.getCurrent() != null) {
- sdkTarget = Sdk.getCurrent().getTarget(project);
- }
-
- if (packageName == null) {
- packageName = ""; //$NON-NLS-1$
- }
- mLastExistingPackageName = packageName;
-
- if (!mValues.projectNameModifiedByUser) {
- mValues.projectName = appName;
- }
-
- if (!mValues.applicationNameModifiedByUser) {
- mValues.applicationName = appName;
- }
-
- if (!mValues.packageNameModifiedByUser) {
- packageName += ".test"; //$NON-NLS-1$
- mValues.packageName = packageName;
- }
-
- if (!mValues.targetModifiedByUser && sdkTarget != null) {
- mValues.target = sdkTarget;
- }
-
- if (!mValues.minSdkModifiedByUser) {
- if (minSdkVersion != null || sdkTarget != null) {
- mValues.minSdk = minSdkVersion;
- }
- if (sdkTarget == null) {
- mValues.updateSdkTargetToMatchMinSdkVersion();
- }
- }
- }
- }
-
- updateTestTargetPackageField(mLastExistingPackageName);
- }
-
- /**
- * Updates the test target package name
- *
- * When using the "self-test" option, the packageName argument is ignored and the
- * current value from the project package is used.
- *
- * Otherwise the packageName is used if it is not null.
- */
- private void updateTestTargetPackageField(String packageName) {
- if (mValues.testingSelf) {
- mValues.testTargetPackageName = mValues.packageName;
- } else if (packageName != null) {
- mValues.testTargetPackageName = packageName;
- }
- }
-
- @Override
- public boolean isPageComplete() {
- // Ensure that the user sees the page and makes a selection
- if (!mPageShown) {
- return false;
- }
-
- return super.isPageComplete();
- }
-
- private void validatePage() {
- String error = null;
-
- if (!mValues.testingSelf) {
- if (mValues.testedProject == null) {
- error = "Please select an existing Android project as a test target.";
- } else if (mValues.projectName.equals(mValues.testedProject.getName())) {
- error = "The main project name and the test project name must be different.";
- }
- }
-
- // -- update UI & enable finish if there's no error
- setPageComplete(error == null);
- if (error != null) {
- setMessage(error, IMessageProvider.ERROR);
- } else {
- setErrorMessage(null);
- setMessage(null);
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetGroup.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetGroup.java
deleted file mode 100644
index fb33a08b4..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetGroup.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-import org.eclipse.jdt.internal.ui.JavaPlugin;
-import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
-import org.eclipse.jdt.internal.ui.workingsets.IWorkingSetIDs;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.ui.IWorkingSet;
-import org.eclipse.ui.dialogs.WorkingSetConfigurationBlock;
-
-/**
- * Copied from
- * org.eclipse.jdt.ui.wizards.NewJavaProjectWizardPageOne$WorkingSetGroup
- *
- * Creates the working set group with controls that allow
- * the selection of working sets
- */
-@SuppressWarnings("restriction")
-public class WorkingSetGroup {
-
- private WorkingSetConfigurationBlock fWorkingSetBlock;
- private Button mEnableButton;
-
- public WorkingSetGroup() {
- String[] workingSetIds = new String[] {
- IWorkingSetIDs.JAVA, IWorkingSetIDs.RESOURCE
- };
- fWorkingSetBlock = new WorkingSetConfigurationBlock(workingSetIds, JavaPlugin.getDefault()
- .getDialogSettings());
- }
-
- public Composite createControl(Composite composite) {
- Group workingSetGroup = new Group(composite, SWT.NONE);
- workingSetGroup.setFont(composite.getFont());
- workingSetGroup.setText(NewWizardMessages.NewJavaProjectWizardPageOne_WorkingSets_group);
- workingSetGroup.setLayout(new GridLayout(1, false));
-
- fWorkingSetBlock.createContent(workingSetGroup);
-
- // WorkingSetGroup is implemented in such a way that the checkbox it contains
- // can only be programmatically set if there's an existing working set associated
- // *before* we construct the control. However the control is created when the
- // wizard is opened, not when the page is first shown.
- //
- // One choice is to duplicate the class in our project.
- // Or find the checkbox we want and trigger it manually.
- mEnableButton = findCheckbox(workingSetGroup);
-
- return workingSetGroup;
- }
-
- public void setWorkingSets(IWorkingSet[] workingSets) {
- fWorkingSetBlock.setWorkingSets(workingSets);
- }
-
- public IWorkingSet[] getSelectedWorkingSets() {
- try {
- return fWorkingSetBlock.getSelectedWorkingSets();
- } catch (Throwable t) {
- // Test scenarios; no UI is created, which the fWorkingSetBlock assumes
- // (it dereferences the enabledButton)
- return new IWorkingSet[0];
- }
- }
-
- public boolean isChecked() {
- return mEnableButton == null ? false : mEnableButton.getSelection();
- }
-
- public void setChecked(boolean state) {
- if (mEnableButton != null) {
- mEnableButton.setSelection(state);
- }
- }
-
- /**
- * Finds the first button of style Checkbox in the given parent composite.
- * Returns null if not found.
- */
- private Button findCheckbox(Composite parent) {
- for (Control control : parent.getChildren()) {
- if (control instanceof Button && (control.getStyle() & SWT.CHECK) == SWT.CHECK) {
- return (Button) control;
- } else if (control instanceof Composite) {
- Button found = findCheckbox((Composite) control);
- if (found != null) {
- return found;
- }
- }
- }
-
- return null;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetHelper.java
deleted file mode 100755
index 428bfd331..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/WorkingSetHelper.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package com.android.ide.eclipse.adt.internal.wizards.newproject;
-
-import org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart;
-import org.eclipse.jdt.internal.ui.workingsets.IWorkingSetIDs;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkingSet;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class contains a helper method to deal with working sets.
- * <p/>
- * Copied from org.eclipse.jdt.ui.wizards.NewJavaProjectWizardPageOne
- */
-@SuppressWarnings("restriction")
-public final class WorkingSetHelper {
-
- private static final IWorkingSet[] EMPTY_WORKING_SET_ARRAY = new IWorkingSet[0];
-
- /** This class is never instantiated. */
- private WorkingSetHelper() {
- }
-
- public static IWorkingSet[] getSelectedWorkingSet(IStructuredSelection selection,
- IWorkbenchPart activePart) {
- IWorkingSet[] selected= getSelectedWorkingSet(selection);
- if (selected != null && selected.length > 0) {
- for (int i= 0; i < selected.length; i++) {
- if (!isValidWorkingSet(selected[i]))
- return EMPTY_WORKING_SET_ARRAY;
- }
- return selected;
- }
-
- if (!(activePart instanceof PackageExplorerPart))
- return EMPTY_WORKING_SET_ARRAY;
-
- PackageExplorerPart explorerPart= (PackageExplorerPart) activePart;
- if (explorerPart.getRootMode() == PackageExplorerPart.PROJECTS_AS_ROOTS) {
- //Get active filter
- IWorkingSet filterWorkingSet= explorerPart.getFilterWorkingSet();
- if (filterWorkingSet == null)
- return EMPTY_WORKING_SET_ARRAY;
-
- if (!isValidWorkingSet(filterWorkingSet))
- return EMPTY_WORKING_SET_ARRAY;
-
- return new IWorkingSet[] {filterWorkingSet};
- } else {
- //If we have been gone into a working set return the working set
- Object input= explorerPart.getViewPartInput();
- if (!(input instanceof IWorkingSet))
- return EMPTY_WORKING_SET_ARRAY;
-
- IWorkingSet workingSet= (IWorkingSet)input;
- if (!isValidWorkingSet(workingSet))
- return EMPTY_WORKING_SET_ARRAY;
-
- return new IWorkingSet[] {workingSet};
- }
- }
-
- private static IWorkingSet[] getSelectedWorkingSet(IStructuredSelection selection) {
- if (!(selection instanceof ITreeSelection))
- return EMPTY_WORKING_SET_ARRAY;
-
- ITreeSelection treeSelection= (ITreeSelection) selection;
- if (treeSelection.isEmpty())
- return EMPTY_WORKING_SET_ARRAY;
-
- List<?> elements = treeSelection.toList();
- if (elements.size() == 1) {
- Object element= elements.get(0);
- TreePath[] paths= treeSelection.getPathsFor(element);
- if (paths.length != 1)
- return EMPTY_WORKING_SET_ARRAY;
-
- TreePath path= paths[0];
- if (path.getSegmentCount() == 0)
- return EMPTY_WORKING_SET_ARRAY;
-
- Object candidate= path.getSegment(0);
- if (!(candidate instanceof IWorkingSet))
- return EMPTY_WORKING_SET_ARRAY;
-
- IWorkingSet workingSetCandidate= (IWorkingSet) candidate;
- if (isValidWorkingSet(workingSetCandidate))
- return new IWorkingSet[] { workingSetCandidate };
-
- return EMPTY_WORKING_SET_ARRAY;
- }
-
- ArrayList<Object> result = new ArrayList<Object>();
- for (Iterator<?> iterator = elements.iterator(); iterator.hasNext();) {
- Object element= iterator.next();
- if (element instanceof IWorkingSet && isValidWorkingSet((IWorkingSet) element)) {
- result.add(element);
- }
- }
- return result.toArray(new IWorkingSet[result.size()]);
- }
-
-
- private static boolean isValidWorkingSet(IWorkingSet workingSet) {
- String id= workingSet.getId();
- if (!IWorkingSetIDs.JAVA.equals(id) && !IWorkingSetIDs.RESOURCE.equals(id))
- return false;
-
- if (workingSet.isAggregateWorkingSet())
- return false;
-
- return true;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/AddTranslationDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/AddTranslationDialog.java
deleted file mode 100644
index 0301b80fe..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/AddTranslationDialog.java
+++ /dev/null
@@ -1,653 +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.newxmlfile;
-
-import static com.android.SdkConstants.FD_RES;
-import static com.android.SdkConstants.FD_RES_VALUES;
-import static com.android.SdkConstants.RES_QUALIFIER_SEP;
-
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.res2.ValueXmlHelper;
-import com.android.ide.common.resources.LocaleManager;
-import com.android.ide.common.resources.ResourceItem;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.layout.configuration.FlagManager;
-import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageControl;
-import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewManager;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.resources.ResourceType;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Maps;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-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.NullProgressMonitor;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.CellLabelProvider;
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TextCellEditor;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-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.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * Dialog which adds a new translation to the project
- */
-public class AddTranslationDialog extends Dialog implements ControlListener, SelectionListener,
- TraverseListener {
- private static final int KEY_COLUMN = 0;
- private static final int DEFAULT_TRANSLATION_COLUMN = 1;
- private static final int NEW_TRANSLATION_COLUMN = 2;
- private final FolderConfiguration mConfiguration = new FolderConfiguration();
- private final IProject mProject;
- private String mTarget;
- private boolean mIgnore;
- private Map<String, String> mTranslations;
- private Set<String> mExistingLanguages;
- private String mSelectedLanguage;
- private String mSelectedRegion;
-
- private Table mTable;
- private Combo mLanguageCombo;
- private Combo mRegionCombo;
- private ImageControl mFlag;
- private Label mFile;
- private Button mOkButton;
- private Composite mErrorPanel;
- private Label mErrorLabel;
- private MyTableViewer mTableViewer;
-
- /**
- * Creates the dialog.
- * @param parentShell the parent shell
- * @param project the project to add translations into
- */
- public AddTranslationDialog(Shell parentShell, IProject project) {
- super(parentShell);
- setShellStyle(SWT.CLOSE | SWT.RESIZE | SWT.TITLE);
- mProject = project;
- }
-
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite container = (Composite) super.createDialogArea(parent);
- GridLayout gl_container = new GridLayout(6, false);
- gl_container.horizontalSpacing = 0;
- container.setLayout(gl_container);
-
- Label languageLabel = new Label(container, SWT.NONE);
- languageLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- languageLabel.setText("Language:");
- mLanguageCombo = new Combo(container, SWT.READ_ONLY);
- GridData gd_mLanguageCombo = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
- gd_mLanguageCombo.widthHint = 150;
- mLanguageCombo.setLayoutData(gd_mLanguageCombo);
-
- Label regionLabel = new Label(container, SWT.NONE);
- GridData gd_regionLabel = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
- gd_regionLabel.horizontalIndent = 10;
- regionLabel.setLayoutData(gd_regionLabel);
- regionLabel.setText("Region:");
- mRegionCombo = new Combo(container, SWT.READ_ONLY);
- GridData gd_mRegionCombo = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
- gd_mRegionCombo.widthHint = 150;
- mRegionCombo.setLayoutData(gd_mRegionCombo);
- mRegionCombo.setEnabled(false);
-
- mFlag = new ImageControl(container, SWT.NONE, null);
- mFlag.setDisposeImage(false);
- GridData gd_mFlag = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
- gd_mFlag.exclude = true;
- gd_mFlag.widthHint = 32;
- gd_mFlag.horizontalIndent = 3;
- mFlag.setLayoutData(gd_mFlag);
-
- mFile = new Label(container, SWT.NONE);
- mFile.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
- mTableViewer = new MyTableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
- mTable = mTableViewer.getTable();
- mTable.setEnabled(false);
- mTable.setLinesVisible(true);
- mTable.setHeaderVisible(true);
- mTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 6, 2));
- mTable.addControlListener(this);
- mTable.addTraverseListener(this);
- // If you have difficulty opening up this form in WindowBuilder and it complains about
- // the next line, change the type of the mTableViewer field and the above
- // constructor call from MyTableViewer to TableViewer
- TableViewerColumn keyViewerColumn = new TableViewerColumn(mTableViewer, SWT.NONE);
- TableColumn keyColumn = keyViewerColumn.getColumn();
- keyColumn.setWidth(100);
- keyColumn.setText("Key");
- TableViewerColumn defaultViewerColumn = new TableViewerColumn(mTableViewer, SWT.NONE);
- TableColumn defaultColumn = defaultViewerColumn.getColumn();
- defaultColumn.setWidth(200);
- defaultColumn.setText("Default");
- TableViewerColumn translationViewerColumn = new TableViewerColumn(mTableViewer, SWT.NONE);
- TableColumn translationColumn = translationViewerColumn.getColumn();
- translationColumn.setWidth(200);
- translationColumn.setText("New Translation");
-
- mErrorPanel = new Composite(container, SWT.NONE);
- GridData gd_mErrorLabel = new GridData(SWT.FILL, SWT.CENTER, false, false, 6, 1);
- gd_mErrorLabel.exclude = true;
- mErrorPanel.setLayoutData(gd_mErrorLabel);
-
- translationViewerColumn.setEditingSupport(new TranslationEditingSupport(mTableViewer));
-
- fillLanguages();
- fillRegions();
- fillStrings();
- updateColumnWidths();
- validatePage();
-
- mLanguageCombo.addSelectionListener(this);
- mRegionCombo.addSelectionListener(this);
-
- return container;
- }
-
- /** Populates the table with keys and default strings */
- private void fillStrings() {
- ResourceManager manager = ResourceManager.getInstance();
- ProjectResources resources = manager.getProjectResources(mProject);
- mExistingLanguages = resources.getLanguages();
-
- Collection<ResourceItem> items = resources.getResourceItemsOfType(ResourceType.STRING);
-
- ResourceItem[] array = items.toArray(new ResourceItem[items.size()]);
- Arrays.sort(array);
-
- // TODO: Read in the actual XML files providing the default keys here
- // (they can be obtained via ResourceItem.getSourceFileList())
- // such that we can read all the attributes associated with each
- // item, and if it defines translatable=false, or the filename is
- // donottranslate.xml, we can ignore it, and in other cases just
- // duplicate all the attributes (such as "formatted=true", or other
- // local conventions such as "product=tablet", or "msgid="123123123",
- // etc.)
-
- mTranslations = Maps.newHashMapWithExpectedSize(items.size());
- IBaseLabelProvider labelProvider = new CellLabelProvider() {
- @Override
- public void update(ViewerCell cell) {
- Object element = cell.getElement();
- int index = cell.getColumnIndex();
- ResourceItem item = (ResourceItem) element;
- switch (index) {
- case KEY_COLUMN: {
- // Key
- cell.setText(item.getName());
- return;
- }
- case DEFAULT_TRANSLATION_COLUMN: {
- // Default translation
- ResourceValue value = item.getResourceValue(ResourceType.STRING,
- mConfiguration, false);
-
- if (value != null) {
- cell.setText(value.getValue());
- return;
- }
- break;
- }
- case NEW_TRANSLATION_COLUMN: {
- // New translation
- String translation = mTranslations.get(item.getName());
- if (translation != null) {
- cell.setText(translation);
- return;
- }
- break;
- }
- default:
- assert false : index;
- }
- cell.setText("");
- }
- };
-
- mTableViewer.setLabelProvider(labelProvider);
- mTableViewer.setContentProvider(new ArrayContentProvider());
- mTableViewer.setInput(array);
- }
-
- /** Populate the languages dropdown */
- private void fillLanguages() {
- List<String> languageCodes = LocaleManager.getLanguageCodes();
- List<String> labels = new ArrayList<String>();
- for (String code : languageCodes) {
- labels.add(code + ": " + LocaleManager.getLanguageName(code)); //$NON-NLS-1$
- }
- Collections.sort(labels);
- labels.add(0, "(Select)");
- mLanguageCombo.setItems(labels.toArray(new String[labels.size()]));
- mLanguageCombo.select(0);
- }
-
- /** Populate the regions dropdown */
- private void fillRegions() {
- // TODO: When you switch languages, offer some "default" usable options. For example,
- // when you choose English, offer the countries that use English, and so on. Unfortunately
- // we don't have good data about this, we'd just need to hardcode a few common cases.
- List<String> regionCodes = LocaleManager.getRegionCodes();
- List<String> labels = new ArrayList<String>();
- for (String code : regionCodes) {
- labels.add(code + ": " + LocaleManager.getRegionName(code)); //$NON-NLS-1$
- }
- Collections.sort(labels);
- labels.add(0, "Any");
- mRegionCombo.setItems(labels.toArray(new String[labels.size()]));
- mRegionCombo.select(0);
- }
-
- /** React to resizing by distributing the space evenly between the last two columns */
- private void updateColumnWidths() {
- Rectangle r = mTable.getClientArea();
- int availableWidth = r.width;
- // Distribute all available space to the last two columns
- int columnCount = mTable.getColumnCount();
- for (int i = 0; i < columnCount; i++) {
- TableColumn column = mTable.getColumn(i);
- availableWidth -= column.getWidth();
- }
- if (availableWidth != 0) {
- TableColumn column = mTable.getColumn(DEFAULT_TRANSLATION_COLUMN);
- column.setWidth(column.getWidth() + availableWidth / 2);
- column = mTable.getColumn(NEW_TRANSLATION_COLUMN);
- column.setWidth(column.getWidth() + availableWidth / 2 + availableWidth % 2);
- }
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- mOkButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
- // Don't make the OK button default as in most dialogs, since when you press
- // Return thinking you might edit a value it dismisses the dialog instead
- false);
- createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
- mOkButton.setEnabled(false);
-
- validatePage();
- }
-
- /**
- * Return the initial size of the dialog.
- */
- @Override
- protected Point getInitialSize() {
- return new Point(800, 600);
- }
-
- private void updateTarget() {
- if (mSelectedLanguage == null) {
- mTarget = null;
- mFile.setText("");
- } else {
- String folder = FD_RES + '/' + FD_RES_VALUES + RES_QUALIFIER_SEP + mSelectedLanguage;
- if (mSelectedRegion != null) {
- folder = folder + RES_QUALIFIER_SEP + 'r' + mSelectedRegion;
- }
- mTarget = folder + "/strings.xml"; //$NON-NLS-1$
- mFile.setText(String.format("Creating %1$s", mTarget));
- }
- }
-
- private void updateFlag() {
- if (mSelectedLanguage == null) {
- // Nothing selected
- ((GridData) mFlag.getLayoutData()).exclude = true;
- } else {
- FlagManager manager = FlagManager.get();
- Image flag = manager.getFlag(mSelectedLanguage, mSelectedRegion);
- if (flag != null) {
- ((GridData) mFlag.getLayoutData()).exclude = false;
- mFlag.setImage(flag);
- }
- }
-
- mFlag.getParent().layout(true);
- mFlag.getParent().redraw();
- }
-
- /** Actually create the new translation file and write it to disk */
- private void createTranslation() {
- List<String> keys = new ArrayList<String>(mTranslations.keySet());
- Collections.sort(keys);
-
- StringBuilder sb = new StringBuilder(keys.size() * 120);
- sb.append("<resources>\n\n"); //$NON-NLS-1$
- for (String key : keys) {
- String value = mTranslations.get(key);
- if (value == null || value.trim().isEmpty()) {
- continue;
- }
- sb.append(" <string name=\""); //$NON-NLS-1$
- sb.append(key);
- sb.append("\">"); //$NON-NLS-1$
- sb.append(ValueXmlHelper.escapeResourceString(value));
- sb.append("</string>\n"); //$NON-NLS-1$
- }
- sb.append("\n</resources>"); //$NON-NLS-1$
-
- IFile file = mProject.getFile(mTarget);
-
- try {
- IContainer parent = file.getParent();
- AdtUtils.ensureExists(parent);
- InputStream source = new ByteArrayInputStream(sb.toString().getBytes(Charsets.UTF_8));
- file.create(source, true, new NullProgressMonitor());
- AdtPlugin.openFile(file, null, true /*showEditorTab*/);
-
- // Ensure that the project resources updates itself to notice the new language.
- // In theory, this shouldn't be necessary.
- ResourceManager manager = ResourceManager.getInstance();
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- IFolder folder = root.getFolder(parent.getFullPath());
- manager.getResourceFolder(folder);
- RenderPreviewManager.bumpRevision();
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
- }
-
- private void validatePage() {
- if (mOkButton == null) { // Early initialization
- return;
- }
-
- String message = null;
-
- if (mSelectedLanguage == null) {
- message = "Select a language";
- } else if (mExistingLanguages.contains(mSelectedLanguage)) {
- if (mSelectedRegion == null) {
- message = String.format("%1$s is already translated in this project",
- LocaleManager.getLanguageName(mSelectedLanguage));
- } else {
- ResourceManager manager = ResourceManager.getInstance();
- ProjectResources resources = manager.getProjectResources(mProject);
- SortedSet<String> regions = resources.getRegions(mSelectedLanguage);
- if (regions.contains(mSelectedRegion)) {
- message = String.format("%1$s (%2$s) is already translated in this project",
- LocaleManager.getLanguageName(mSelectedLanguage),
- LocaleManager.getRegionName(mSelectedRegion));
- }
- }
- } else {
- // Require all strings to be translated? No, some of these may not
- // be translatable (e.g. translatable=false, defined in donottranslate.xml, etc.)
- //int missing = mTable.getItemCount() - mTranslations.values().size();
- //if (missing > 0) {
- // message = String.format("Missing %1$d translations", missing);
- //}
- }
-
- boolean valid = message == null;
- mTable.setEnabled(message == null);
- mOkButton.setEnabled(valid);
- showError(message);
- }
-
- private void showError(String error) {
- GridData data = (GridData) mErrorPanel.getLayoutData();
-
- boolean show = error != null;
- if (show == data.exclude) {
- if (show) {
- if (mErrorLabel == null) {
- mErrorPanel.setLayout(new GridLayout(2, false));
- IWorkbench workbench = PlatformUI.getWorkbench();
- ISharedImages sharedImages = workbench.getSharedImages();
- String iconName = ISharedImages.IMG_OBJS_ERROR_TSK;
- Image image = sharedImages.getImage(iconName);
- @SuppressWarnings("unused")
- ImageControl icon = new ImageControl(mErrorPanel, SWT.NONE, image);
-
- mErrorLabel = new Label(mErrorPanel, SWT.NONE);
- mErrorLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
- 1, 1));
- }
- mErrorLabel.setText(error);
- }
- data.exclude = !show;
- mErrorPanel.getParent().layout(true);
- }
- }
-
- @Override
- protected void okPressed() {
- mTableViewer.applyEditorValue();
-
- super.okPressed();
- createTranslation();
- }
-
- // ---- Implements ControlListener ----
-
- @Override
- public void controlMoved(ControlEvent e) {
- }
-
- @Override
- public void controlResized(ControlEvent e) {
- if (mIgnore) {
- return;
- }
-
- updateColumnWidths();
- }
-
- // ---- Implements SelectionListener ----
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (mIgnore) {
- return;
- }
-
- Object source = e.getSource();
- if (source == mLanguageCombo) {
- try {
- mIgnore = true;
- mRegionCombo.select(0);
- mSelectedRegion = null;
- } finally {
- mIgnore = false;
- }
-
- int languageIndex = mLanguageCombo.getSelectionIndex();
- if (languageIndex == 0) {
- mSelectedLanguage = null;
- mRegionCombo.setEnabled(false);
- } else {
- // This depends on the label format
- mSelectedLanguage = mLanguageCombo.getItem(languageIndex).substring(0, 2);
- mRegionCombo.setEnabled(true);
- }
-
- updateTarget();
- updateFlag();
- } else if (source == mRegionCombo) {
- int regionIndex = mRegionCombo.getSelectionIndex();
- if (regionIndex == 0) {
- mSelectedRegion = null;
- } else {
- mSelectedRegion = mRegionCombo.getItem(regionIndex).substring(0, 2);
- }
-
- updateTarget();
- updateFlag();
- }
-
- try {
- mIgnore = true;
- validatePage();
- } finally {
- mIgnore = false;
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- // ---- TraverseListener ----
-
- @Override
- public void keyTraversed(TraverseEvent e) {
- // If you press Return and we're not cell editing, start editing the current row
- if (e.detail == SWT.TRAVERSE_RETURN && !mTableViewer.isCellEditorActive()) {
- int index = mTable.getSelectionIndex();
- if (index != -1) {
- Object next = mTable.getItem(index).getData();
- mTableViewer.editElement(next, NEW_TRANSLATION_COLUMN);
- }
- }
- }
-
- /** Editing support for the translation column */
- private class TranslationEditingSupport extends EditingSupport {
- /**
- * When true, setValue is being called as part of a default action
- * (e.g. Return), not due to focus loss
- */
- private boolean mDefaultAction;
-
- private TranslationEditingSupport(ColumnViewer viewer) {
- super(viewer);
- }
-
- @Override
- protected void setValue(Object element, Object value) {
- ResourceItem item = (ResourceItem) element;
- mTranslations.put(item.getName(), value.toString());
- mTableViewer.update(element, null);
- validatePage();
-
- // If the user is pressing Return to finish editing a value (which is
- // not the only way this method can get called - for example, if you click
- // outside the cell while editing, the focus loss will also result in
- // this method getting called), then mDefaultAction is true, and we automatically
- // start editing the next row.
- if (mDefaultAction) {
- mTable.getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (!mTable.isDisposed() && !mTableViewer.isCellEditorActive()) {
- int index = mTable.getSelectionIndex();
- if (index != -1 && index < mTable.getItemCount() - 1) {
- Object next = mTable.getItem(index + 1).getData();
- mTableViewer.editElement(next, NEW_TRANSLATION_COLUMN);
- }
- }
- }
- });
- }
- }
-
- @Override
- protected Object getValue(Object element) {
- ResourceItem item = (ResourceItem) element;
- String value = mTranslations.get(item.getName());
- if (value == null) {
- return "";
- }
- return value;
- }
-
- @Override
- protected CellEditor getCellEditor(Object element) {
- return new TextCellEditor(mTable) {
- @Override
- protected void handleDefaultSelection(SelectionEvent event) {
- try {
- mDefaultAction = true;
- super.handleDefaultSelection(event);
- } finally {
- mDefaultAction = false;
- }
- }
- };
- }
-
- @Override
- protected boolean canEdit(Object element) {
- return true;
- }
- }
-
- private class MyTableViewer extends TableViewer {
- public MyTableViewer(Composite parent, int style) {
- super(parent, style);
- }
-
- // Make this public so we can call it to ensure values are applied before the dialog
- // is dismissed in {@link #okPressed}
- @Override
- public void applyEditorValue() {
- super.applyEditorValue();
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java
deleted file mode 100644
index 1d6467e64..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/ChooseConfigurationPage.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2011 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.newxmlfile;
-
-import com.android.SdkConstants;
-import com.android.ide.common.resources.configuration.ResourceQualifier;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
-import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.SelectorMode;
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard.Values;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.wizard.IWizardPage;
-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.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Second page of the {@link NewXmlFileWizard}.
- * <p>
- * This page is used for choosing the current configuration or specific resource
- * folder.
- */
-public class ChooseConfigurationPage extends WizardPage {
- private Values mValues;
- private Text mWsFolderPathTextField;
- private ConfigurationSelector mConfigSelector;
- private boolean mInternalWsFolderPathUpdate;
- private boolean mInternalConfigSelectorUpdate;
-
- /** Absolute destination folder root, e.g. "/res/" */
- static final String RES_FOLDER_ABS = AdtConstants.WS_RESOURCES + AdtConstants.WS_SEP;
- /** Relative destination folder root, e.g. "res/" */
- static final String RES_FOLDER_REL = SdkConstants.FD_RESOURCES + AdtConstants.WS_SEP;
-
- /**
- * Create the wizard.
- *
- * @param values value object holding current wizard state
- */
- public ChooseConfigurationPage(NewXmlFileWizard.Values values) {
- super("chooseConfig");
- mValues = values;
- setTitle("Choose Configuration Folder");
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- if (mValues.folderPath != null) {
- mWsFolderPathTextField.setText(mValues.folderPath);
- }
- }
- }
-
- @Override
- public void createControl(Composite parent) {
- // This UI is maintained with WindowBuilder.
-
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayout(new GridLayout(2, false /* makeColumnsEqualWidth */));
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- // label before configuration selector
- Label label = new Label(composite, SWT.NONE);
- label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
- label.setText("Optional: Choose a specific configuration to limit the XML to:");
-
- // configuration selector
- mConfigSelector = new ConfigurationSelector(composite, SelectorMode.DEFAULT);
- GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
- gd.verticalAlignment = SWT.FILL;
- gd.horizontalAlignment = SWT.FILL;
- gd.horizontalSpan = 2;
- gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
- mConfigSelector.setLayoutData(gd);
- mConfigSelector.setOnChangeListener(new ConfigurationChangeListener());
-
- // Folder name: [text]
- String tooltip = "The folder where the file will be generated, relative to the project.";
-
- Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
- GridData gdSeparator = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1);
- gdSeparator.heightHint = 10;
- separator.setLayoutData(gdSeparator);
- Label folderLabel = new Label(composite, SWT.NONE);
- folderLabel.setText("Folder:");
- folderLabel.setToolTipText(tooltip);
-
- mWsFolderPathTextField = new Text(composite, SWT.BORDER);
- mWsFolderPathTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mWsFolderPathTextField.setToolTipText(tooltip);
- mWsFolderPathTextField.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onWsFolderPathUpdated();
- }
- });
-
- setControl(composite);
-
- mConfigSelector.setConfiguration(mValues.configuration);
- }
-
- /**
- * Callback called when the Folder text field is changed, either programmatically
- * or by the user.
- */
- private void onWsFolderPathUpdated() {
- if (mInternalWsFolderPathUpdate) {
- return;
- }
-
- String wsFolderPath = mWsFolderPathTextField.getText();
-
- // This is a custom path, we need to sanitize it.
- // First it should start with "/res/". Then we need to make sure there are no
- // relative paths, things like "../" or "./" or even "//".
- wsFolderPath = wsFolderPath.replaceAll("/+\\.\\./+|/+\\./+|//+|\\\\+|^/+", "/"); //$NON-NLS-1$ //$NON-NLS-2$
- wsFolderPath = wsFolderPath.replaceAll("^\\.\\./+|^\\./+", ""); //$NON-NLS-1$ //$NON-NLS-2$
- wsFolderPath = wsFolderPath.replaceAll("/+\\.\\.$|/+\\.$|/+$", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
- // We get "res/foo" from selections relative to the project when we want a "/res/foo" path.
- if (wsFolderPath.startsWith(RES_FOLDER_REL)) {
- wsFolderPath = RES_FOLDER_ABS + wsFolderPath.substring(RES_FOLDER_REL.length());
-
- mInternalWsFolderPathUpdate = true;
- mWsFolderPathTextField.setText(wsFolderPath);
- mInternalWsFolderPathUpdate = false;
- }
-
- mValues.folderPath = wsFolderPath;
-
- if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
- wsFolderPath = wsFolderPath.substring(RES_FOLDER_ABS.length());
-
- int pos = wsFolderPath.indexOf(AdtConstants.WS_SEP_CHAR);
- if (pos >= 0) {
- wsFolderPath = wsFolderPath.substring(0, pos);
- }
-
- String[] folderSegments = wsFolderPath.split(SdkConstants.RES_QUALIFIER_SEP);
-
- if (folderSegments.length > 0) {
- String folderName = folderSegments[0];
-
- // update config selector
- mInternalConfigSelectorUpdate = true;
- mConfigSelector.setConfiguration(folderSegments);
- mInternalConfigSelectorUpdate = false;
-
- IWizardPage previous = ((NewXmlFileWizard) getWizard()).getPreviousPage(this);
- if (previous instanceof NewXmlFileCreationPage) {
- NewXmlFileCreationPage p = (NewXmlFileCreationPage) previous;
- p.selectTypeFromFolder(folderName);
- }
- }
- }
-
- validatePage();
- }
-
- /**
- * Callback called when the configuration has changed in the {@link ConfigurationSelector}.
- */
- private class ConfigurationChangeListener implements Runnable {
- @Override
- public void run() {
- if (mInternalConfigSelectorUpdate) {
- return;
- }
-
- resetFolderPath(true /*validate*/);
- }
- }
-
- /**
- * Reset the current Folder path based on the UI selection
- * @param validate if true, force a call to {@link #validatePage()}.
- */
- private void resetFolderPath(boolean validate) {
- TypeInfo type = mValues.type;
- if (type != null) {
- mConfigSelector.getConfiguration(mValues.configuration);
- StringBuilder sb = new StringBuilder(RES_FOLDER_ABS);
- sb.append(mValues.configuration.getFolderName(type.getResFolderType()));
-
- mInternalWsFolderPathUpdate = true;
- String newPath = sb.toString();
- mValues.folderPath = newPath;
- mWsFolderPathTextField.setText(newPath);
- mInternalWsFolderPathUpdate = false;
-
- if (validate) {
- validatePage();
- }
- }
- }
-
- /**
- * Returns the destination folder path relative to the project or an empty string.
- *
- * @return the currently edited folder
- */
- public String getWsFolderPath() {
- return mWsFolderPathTextField == null ? "" : mWsFolderPathTextField.getText(); //$NON-NLS-1$
- }
-
- /**
- * Validates the fields, displays errors and warnings.
- * Enables the finish button if there are no errors.
- */
- private void validatePage() {
- String error = null;
- String warning = null;
-
- // -- validate folder configuration
- if (error == null) {
- ConfigurationState state = mConfigSelector.getState();
- if (state == ConfigurationState.INVALID_CONFIG) {
- ResourceQualifier qual = mConfigSelector.getInvalidQualifier();
- if (qual != null) {
- error =
- String.format("The qualifier '%1$s' is invalid in the folder configuration.",
- qual.getName());
- }
- } else if (state == ConfigurationState.REGION_WITHOUT_LANGUAGE) {
- error = "The Region qualifier requires the Language qualifier.";
- }
- }
-
- // -- validate generated path
- if (error == null) {
- String wsFolderPath = getWsFolderPath();
- if (!wsFolderPath.startsWith(RES_FOLDER_ABS)) {
- error = String.format("Target folder must start with %1$s.", RES_FOLDER_ABS);
- }
- }
-
- // -- validate destination file doesn't exist
- if (error == null) {
- IFile file = mValues.getDestinationFile();
- if (file != null && file.exists()) {
- warning = "The destination file already exists";
- }
- }
-
- // -- update UI & enable finish if there's no error
- setPageComplete(error == null);
- if (error != null) {
- setMessage(error, IMessageProvider.ERROR);
- } else if (warning != null) {
- setMessage(warning, IMessageProvider.WARNING);
- } else {
- setErrorMessage(null);
- setMessage(null);
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java
deleted file mode 100644
index 28fb8c032..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * Copyright (C) 2008 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.newxmlfile;
-
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.HORIZONTAL_SCROLL_VIEW;
-import static com.android.SdkConstants.LINEAR_LAYOUT;
-import static com.android.SdkConstants.RES_QUALIFIER_SEP;
-import static com.android.SdkConstants.SCROLL_VIEW;
-import static com.android.SdkConstants.VALUE_FILL_PARENT;
-import static com.android.SdkConstants.VALUE_MATCH_PARENT;
-import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP_CHAR;
-import static com.android.ide.eclipse.adt.internal.wizards.newxmlfile.ChooseConfigurationPage.RES_FOLDER_ABS;
-
-import com.android.SdkConstants;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.ResourceQualifier;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
-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.resources.ResourceNameValidator;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk.TargetChangeListener;
-import com.android.resources.ResourceFolderType;
-import com.android.sdklib.IAndroidTarget;
-import com.android.utils.Pair;
-import com.android.utils.SdkUtils;
-
-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.IAdaptable;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-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.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.FileEditorInput;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * This is the first page of the {@link NewXmlFileWizard} which provides the ability to create
- * skeleton XML resources files for Android projects.
- * <p/>
- * This page is used to select the project, resource type and file name.
- */
-class NewXmlFileCreationPage extends WizardPage {
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- // Ensure the initial focus is in the Name field; you usually don't need
- // to edit the default text field (the project name)
- if (visible && mFileNameTextField != null) {
- mFileNameTextField.setFocus();
- }
-
- validatePage();
- }
-
- /**
- * Information on one type of resource that can be created (e.g. menu, pref, layout, etc.)
- */
- static class TypeInfo {
- private final String mUiName;
- private final ResourceFolderType mResFolderType;
- private final String mTooltip;
- private final Object mRootSeed;
- private ArrayList<String> mRoots = new ArrayList<String>();
- private final String mXmlns;
- private final String mDefaultAttrs;
- private final String mDefaultRoot;
- private final int mTargetApiLevel;
-
- public TypeInfo(String uiName,
- String tooltip,
- ResourceFolderType resFolderType,
- Object rootSeed,
- String defaultRoot,
- String xmlns,
- String defaultAttrs,
- int targetApiLevel) {
- mUiName = uiName;
- mResFolderType = resFolderType;
- mTooltip = tooltip;
- mRootSeed = rootSeed;
- mDefaultRoot = defaultRoot;
- mXmlns = xmlns;
- mDefaultAttrs = defaultAttrs;
- mTargetApiLevel = targetApiLevel;
- }
-
- /** Returns the UI name for the resource type. Unique. Never null. */
- String getUiName() {
- return mUiName;
- }
-
- /** Returns the tooltip for the resource type. Can be null. */
- String getTooltip() {
- return mTooltip;
- }
-
- /**
- * Returns the name of the {@link ResourceFolderType}.
- * Never null but not necessarily unique,
- * e.g. two types use {@link ResourceFolderType#XML}.
- */
- String getResFolderName() {
- return mResFolderType.getName();
- }
-
- /**
- * Returns the matching {@link ResourceFolderType}.
- * Never null but not necessarily unique,
- * e.g. two types use {@link ResourceFolderType#XML}.
- */
- ResourceFolderType getResFolderType() {
- return mResFolderType;
- }
-
- /**
- * Returns the seed used to fill the root element values.
- * The seed might be either a String, a String array, an {@link ElementDescriptor},
- * a {@link DocumentDescriptor} or null.
- */
- Object getRootSeed() {
- return mRootSeed;
- }
-
- /**
- * Returns the default root element that should be selected by default. Can be
- * null.
- *
- * @param project the associated project, or null if not known
- */
- String getDefaultRoot(IProject project) {
- return mDefaultRoot;
- }
-
- /**
- * Returns the list of all possible root elements for the resource type.
- * This can be an empty ArrayList but not null.
- * <p/>
- * TODO: the root list SHOULD depend on the currently selected project, to include
- * custom classes.
- */
- ArrayList<String> getRoots() {
- return mRoots;
- }
-
- /**
- * If the generated resource XML file requires an "android" XMLNS, this should be set
- * to {@link SdkConstants#NS_RESOURCES}. When it is null, no XMLNS is generated.
- */
- String getXmlns() {
- return mXmlns;
- }
-
- /**
- * When not null, this represent extra attributes that must be specified in the
- * root element of the generated XML file. When null, no extra attributes are inserted.
- *
- * @param project the project to get the attributes for
- * @param root the selected root element string, never null
- */
- String getDefaultAttrs(IProject project, String root) {
- return mDefaultAttrs;
- }
-
- /**
- * When not null, represents an extra string that should be written inside
- * the element when constructed
- *
- * @param project the project to get the child content for
- * @param root the chosen root element
- * @return a string to be written inside the root element, or null if nothing
- */
- String getChild(IProject project, String root) {
- return null;
- }
-
- /**
- * The minimum API level required by the current SDK target to support this feature.
- *
- * @return the minimum API level
- */
- public int getTargetApiLevel() {
- return mTargetApiLevel;
- }
- }
-
- /**
- * TypeInfo, information for each "type" of file that can be created.
- */
- private static final TypeInfo[] sTypes = {
- new TypeInfo(
- "Layout", // UI name
- "An XML file that describes a screen layout.", // tooltip
- ResourceFolderType.LAYOUT, // folder type
- AndroidTargetData.DESCRIPTOR_LAYOUT, // root seed
- LINEAR_LAYOUT, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- "", // not used, see below
- 1 // target API level
- ) {
-
- @Override
- String getDefaultRoot(IProject project) {
- // TODO: Use GridLayout by default for new SDKs
- // (when we've ironed out all the usability issues)
- //Sdk currentSdk = Sdk.getCurrent();
- //if (project != null && currentSdk != null) {
- // IAndroidTarget target = currentSdk.getTarget(project);
- // // fill_parent was renamed match_parent in API level 8
- // if (target != null && target.getVersion().getApiLevel() >= 13) {
- // return GRID_LAYOUT;
- // }
- //}
-
- return LINEAR_LAYOUT;
- };
-
- // The default attributes must be determined dynamically since whether
- // we use match_parent or fill_parent depends on the API level of the
- // project
- @Override
- String getDefaultAttrs(IProject project, String root) {
- Sdk currentSdk = Sdk.getCurrent();
- String fill = VALUE_FILL_PARENT;
- if (currentSdk != null) {
- IAndroidTarget target = currentSdk.getTarget(project);
- // fill_parent was renamed match_parent in API level 8
- if (target != null && target.getVersion().getApiLevel() >= 8) {
- fill = VALUE_MATCH_PARENT;
- }
- }
-
- // Only set "vertical" orientation of LinearLayouts by default;
- // for GridLayouts for example we want to rely on the real default
- // of the layout
- String size = String.format(
- "android:layout_width=\"%1$s\"\n" //$NON-NLS-1$
- + "android:layout_height=\"%2$s\"", //$NON-NLS-1$
- fill, fill);
- if (LINEAR_LAYOUT.equals(root)) {
- return "android:orientation=\"vertical\"\n" + size; //$NON-NLS-1$
- } else {
- return size;
- }
- }
-
- @Override
- String getChild(IProject project, String root) {
- // Create vertical linear layouts inside new scroll views
- if (SCROLL_VIEW.equals(root) || HORIZONTAL_SCROLL_VIEW.equals(root)) {
- return " <LinearLayout " //$NON-NLS-1$
- + getDefaultAttrs(project, root).replace('\n', ' ')
- + " android:orientation=\"vertical\"" //$NON-NLS-1$
- + "></LinearLayout>\n"; //$NON-NLS-1$
- }
- return null;
- }
- },
- new TypeInfo("Values", // UI name
- "An XML file with simple values: colors, strings, dimensions, etc.", // tooltip
- ResourceFolderType.VALUES, // folder type
- SdkConstants.TAG_RESOURCES, // root seed
- null, // default root
- null, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("Drawable", // UI name
- "An XML file that describes a drawable.", // tooltip
- ResourceFolderType.DRAWABLE, // folder type
- AndroidTargetData.DESCRIPTOR_DRAWABLE, // root seed
- null, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("Menu", // UI name
- "An XML file that describes an menu.", // tooltip
- ResourceFolderType.MENU, // folder type
- SdkConstants.TAG_MENU, // root seed
- null, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("Color List", // UI name
- "An XML file that describes a color state list.", // tooltip
- ResourceFolderType.COLOR, // folder type
- AndroidTargetData.DESCRIPTOR_COLOR, // root seed
- "selector", //$NON-NLS-1$ // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("Property Animation", // UI name
- "An XML file that describes a property animation", // tooltip
- ResourceFolderType.ANIMATOR, // folder type
- AndroidTargetData.DESCRIPTOR_ANIMATOR, // root seed
- "set", //$NON-NLS-1$ // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 11 // target API level
- ),
- new TypeInfo("Tween Animation", // UI name
- "An XML file that describes a tween animation.", // tooltip
- ResourceFolderType.ANIM, // folder type
- AndroidTargetData.DESCRIPTOR_ANIM, // root seed
- "set", //$NON-NLS-1$ // default root
- null, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("AppWidget Provider", // UI name
- "An XML file that describes a widget provider.", // tooltip
- ResourceFolderType.XML, // folder type
- AndroidTargetData.DESCRIPTOR_APPWIDGET_PROVIDER, // root seed
- null, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 3 // target API level
- ),
- new TypeInfo("Preference", // UI name
- "An XML file that describes preferences.", // tooltip
- ResourceFolderType.XML, // folder type
- AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed
- SdkConstants.CLASS_NAME_PREFERENCE_SCREEN, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- new TypeInfo("Searchable", // UI name
- "An XML file that describes a searchable.", // tooltip
- ResourceFolderType.XML, // folder type
- AndroidTargetData.DESCRIPTOR_SEARCHABLE, // root seed
- null, // default root
- SdkConstants.NS_RESOURCES, // xmlns
- null, // default attributes
- 1 // target API level
- ),
- // Still missing: Interpolator, Raw and Mipmap. Raw should probably never be in
- // this menu since it's not often used for creating XML files.
- };
-
- private NewXmlFileWizard.Values mValues;
- private ProjectCombo mProjectButton;
- private Text mFileNameTextField;
- private Combo mTypeCombo;
- private IStructuredSelection mInitialSelection;
- private ResourceFolderType mInitialFolderType;
- private boolean mInternalTypeUpdate;
- private TargetChangeListener mSdkTargetChangeListener;
- private Table mRootTable;
- private TableViewer mRootTableViewer;
-
- // --- UI creation ---
-
- /**
- * Constructs a new {@link NewXmlFileCreationPage}.
- * <p/>
- * Called by {@link NewXmlFileWizard#createMainPage}.
- */
- protected NewXmlFileCreationPage(String pageName, NewXmlFileWizard.Values values) {
- super(pageName);
- mValues = values;
- setPageComplete(false);
- }
-
- public void setInitialSelection(IStructuredSelection initialSelection) {
- mInitialSelection = initialSelection;
- }
-
- public void setInitialFolderType(ResourceFolderType initialType) {
- mInitialFolderType = initialType;
- }
-
- /**
- * Called by the parent Wizard to create the UI for this Wizard Page.
- *
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
- */
- @Override
- @SuppressWarnings("unused") // SWT constructors have side effects, they aren't unused
- public void createControl(Composite parent) {
- // This UI is maintained with WindowBuilder.
-
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayout(new GridLayout(2, false /*makeColumnsEqualWidth*/));
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- // label before type radios
- Label typeLabel = new Label(composite, SWT.NONE);
- typeLabel.setText("Resource Type:");
-
- mTypeCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
- mTypeCombo.setToolTipText("What type of resource would you like to create?");
- mTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (mInitialFolderType != null) {
- mTypeCombo.setEnabled(false);
- }
- mTypeCombo.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- TypeInfo type = getSelectedType();
- if (type != null) {
- onSelectType(type);
- }
- }
- });
-
- // separator
- Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
- GridData gd2 = new GridData(GridData.GRAB_HORIZONTAL);
- gd2.horizontalAlignment = SWT.FILL;
- gd2.horizontalSpan = 2;
- separator.setLayoutData(gd2);
-
- // Project: [button]
- String tooltip = "The Android Project where the new resource file will be created.";
- Label projectLabel = new Label(composite, SWT.NONE);
- projectLabel.setText("Project:");
- projectLabel.setToolTipText(tooltip);
-
- ProjectChooserHelper helper =
- new ProjectChooserHelper(getShell(), null /* filter */);
-
- mProjectButton = new ProjectCombo(helper, composite, mValues.project);
- mProjectButton.setToolTipText(tooltip);
- mProjectButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mProjectButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- IProject project = mProjectButton.getSelectedProject();
- if (project != mValues.project) {
- changeProject(project);
- }
- };
- });
-
- // Filename: [text]
- Label fileLabel = new Label(composite, SWT.NONE);
- fileLabel.setText("File:");
- fileLabel.setToolTipText("The name of the resource file to create.");
-
- mFileNameTextField = new Text(composite, SWT.BORDER);
- mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mFileNameTextField.setToolTipText(tooltip);
- mFileNameTextField.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- mValues.name = mFileNameTextField.getText();
- validatePage();
- }
- });
-
- // separator
- Label rootSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
- GridData gd = new GridData(GridData.GRAB_HORIZONTAL);
- gd.horizontalAlignment = SWT.FILL;
- gd.horizontalSpan = 2;
- rootSeparator.setLayoutData(gd);
-
- // Root Element:
- // [TableViewer]
- Label rootLabel = new Label(composite, SWT.NONE);
- rootLabel.setText("Root Element:");
- new Label(composite, SWT.NONE);
-
- mRootTableViewer = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
- mRootTable = mRootTableViewer.getTable();
- GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
- tableGridData.heightHint = 200;
- mRootTable.setLayoutData(tableGridData);
-
- setControl(composite);
-
- // Update state the first time
- setErrorMessage(null);
- setMessage(null);
-
- initializeFromSelection(mInitialSelection);
- updateAvailableTypes();
- initializeFromFixedType();
- initializeRootValues();
- installTargetChangeListener();
-
- initialSelectType();
- validatePage();
- }
-
- private void initialSelectType() {
- TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
- int typeIndex = getTypeComboIndex(mValues.type);
- if (typeIndex == -1) {
- typeIndex = 0;
- } else {
- assert mValues.type == types[typeIndex];
- }
- mTypeCombo.select(typeIndex);
- onSelectType(types[typeIndex]);
- updateRootCombo(types[typeIndex]);
- }
-
- private void installTargetChangeListener() {
- mSdkTargetChangeListener = new TargetChangeListener() {
- @Override
- public IProject getProject() {
- return mValues.project;
- }
-
- @Override
- public void reload() {
- if (mValues.project != null) {
- changeProject(mValues.project);
- }
- }
- };
-
- AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
- }
-
- @Override
- public void dispose() {
-
- if (mSdkTargetChangeListener != null) {
- AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
- mSdkTargetChangeListener = null;
- }
-
- super.dispose();
- }
-
- /**
- * Returns the selected root element string, if any.
- *
- * @return The selected root element string or null.
- */
- public String getRootElement() {
- int index = mRootTable.getSelectionIndex();
- if (index >= 0) {
- Object[] roots = (Object[]) mRootTableViewer.getInput();
- return roots[index].toString();
- }
- return null;
- }
-
- /**
- * Called by {@link NewXmlFileWizard} to initialize the page with the selection
- * received by the wizard -- typically the current user workbench selection.
- * <p/>
- * Things we expect to find out from the selection:
- * <ul>
- * <li>The project name, valid if it's an android nature.</li>
- * <li>The current folder, valid if it's a folder under /res</li>
- * <li>An existing filename, in which case the user will be asked whether to override it.</li>
- * </ul>
- * <p/>
- * The selection can also be set to a {@link Pair} of {@link IProject} and a workspace
- * resource path (where the resource path does not have to exist yet, such as res/anim/).
- *
- * @param selection The selection when the wizard was initiated.
- */
- private boolean initializeFromSelection(IStructuredSelection selection) {
- if (selection == null) {
- return false;
- }
-
- // Find the best match in the element list. In case there are multiple selected elements
- // select the one that provides the most information and assign them a score,
- // e.g. project=1 + folder=2 + file=4.
- IProject targetProject = null;
- String targetWsFolderPath = null;
- String targetFileName = null;
- int targetScore = 0;
- for (Object element : selection.toList()) {
- if (element instanceof IAdaptable) {
- IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class);
- IProject project = res != null ? res.getProject() : null;
-
- // Is this an Android project?
- try {
- if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) {
- continue;
- }
- } catch (CoreException e) {
- // checking the nature failed, ignore this resource
- continue;
- }
-
- int score = 1; // we have a valid project at least
-
- IPath wsFolderPath = null;
- String fileName = null;
- assert res != null; // Eclipse incorrectly thinks res could be null, so tell it no
- if (res.getType() == IResource.FOLDER) {
- wsFolderPath = res.getProjectRelativePath();
- } else if (res.getType() == IResource.FILE) {
- if (SdkUtils.endsWithIgnoreCase(res.getName(), DOT_XML)) {
- fileName = res.getName();
- }
- wsFolderPath = res.getParent().getProjectRelativePath();
- }
-
- // Disregard this folder selection if it doesn't point to /res/something
- if (wsFolderPath != null &&
- wsFolderPath.segmentCount() > 1 &&
- SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) {
- score += 2;
- } else {
- wsFolderPath = null;
- fileName = null;
- }
-
- score += fileName != null ? 4 : 0;
-
- if (score > targetScore) {
- targetScore = score;
- targetProject = project;
- targetWsFolderPath = wsFolderPath != null ? wsFolderPath.toString() : null;
- targetFileName = fileName;
- }
- } else if (element instanceof Pair<?,?>) {
- // Pair of Project/String
- @SuppressWarnings("unchecked")
- Pair<IProject,String> pair = (Pair<IProject,String>)element;
- targetScore = 1;
- targetProject = pair.getFirst();
- targetWsFolderPath = pair.getSecond();
- targetFileName = "";
- }
- }
-
- if (targetProject == null) {
- // Try to figure out the project from the active editor
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (window != null) {
- IWorkbenchPage page = window.getActivePage();
- if (page != null) {
- IEditorPart activeEditor = page.getActiveEditor();
- if (activeEditor instanceof AndroidXmlEditor) {
- Object input = ((AndroidXmlEditor) activeEditor).getEditorInput();
- if (input instanceof FileEditorInput) {
- FileEditorInput fileInput = (FileEditorInput) input;
- targetScore = 1;
- IFile file = fileInput.getFile();
- targetProject = file.getProject();
- IPath path = file.getParent().getProjectRelativePath();
- targetWsFolderPath = path != null ? path.toString() : null;
- }
- }
- }
- }
- }
-
- if (targetProject == null) {
- // If we didn't find a default project based on the selection, check how many
- // open Android projects we can find in the current workspace. If there's only
- // one, we'll just select it by default.
- IJavaProject[] projects = AdtUtils.getOpenAndroidProjects();
- if (projects != null && projects.length == 1) {
- targetScore = 1;
- targetProject = projects[0].getProject();
- }
- }
-
- // Now set the UI accordingly
- if (targetScore > 0) {
- mValues.project = targetProject;
- mValues.folderPath = targetWsFolderPath;
- mProjectButton.setSelectedProject(targetProject);
- mFileNameTextField.setText(targetFileName != null ? targetFileName : ""); //$NON-NLS-1$
-
- // If the current selection context corresponds to a specific file type,
- // select it.
- if (targetWsFolderPath != null) {
- int pos = targetWsFolderPath.lastIndexOf(WS_SEP_CHAR);
- if (pos >= 0) {
- targetWsFolderPath = targetWsFolderPath.substring(pos + 1);
- }
- String[] folderSegments = targetWsFolderPath.split(RES_QUALIFIER_SEP);
- if (folderSegments.length > 0) {
- mValues.configuration = FolderConfiguration.getConfig(folderSegments);
- String folderName = folderSegments[0];
- selectTypeFromFolder(folderName);
- }
- }
- }
-
- return true;
- }
-
- private void initializeFromFixedType() {
- if (mInitialFolderType != null) {
- for (TypeInfo type : sTypes) {
- if (type.getResFolderType() == mInitialFolderType) {
- mValues.type = type;
- updateFolderPath(type);
- break;
- }
- }
- }
- }
-
- /**
- * Given a folder name, such as "drawable", select the corresponding type in
- * the dropdown.
- */
- void selectTypeFromFolder(String folderName) {
- List<TypeInfo> matches = new ArrayList<TypeInfo>();
- boolean selected = false;
-
- TypeInfo selectedType = getSelectedType();
- for (TypeInfo type : sTypes) {
- if (type.getResFolderName().equals(folderName)) {
- matches.add(type);
- selected |= type == selectedType;
- }
- }
-
- if (matches.size() == 1) {
- // If there's only one match, select it if it's not already selected
- if (!selected) {
- selectType(matches.get(0));
- }
- } else if (matches.size() > 1) {
- // There are multiple type candidates for this folder. This can happen
- // for /res/xml for example. Check to see if one of them is currently
- // selected. If yes, leave the selection unchanged. If not, deselect all type.
- if (!selected) {
- selectType(null);
- }
- } else {
- // Nothing valid was selected.
- selectType(null);
- }
- }
-
- /**
- * Initialize the root values of the type infos based on the current framework values.
- */
- private void initializeRootValues() {
- IProject project = mValues.project;
- for (TypeInfo type : sTypes) {
- // Clear all the roots for this type
- ArrayList<String> roots = type.getRoots();
- if (roots.size() > 0) {
- roots.clear();
- }
-
- // depending of the type of the seed, initialize the root in different ways
- Object rootSeed = type.getRootSeed();
-
- if (rootSeed instanceof String) {
- // The seed is a single string, Add it as-is.
- roots.add((String) rootSeed);
- } else if (rootSeed instanceof String[]) {
- // The seed is an array of strings. Add them as-is.
- for (String value : (String[]) rootSeed) {
- roots.add(value);
- }
- } else if (rootSeed instanceof Integer && project != null) {
- // The seed is a descriptor reference defined in AndroidTargetData.DESCRIPTOR_*
- // In this case add all the children element descriptors defined, recursively,
- // and avoid infinite recursion by keeping track of what has already been added.
-
- // Note: if project is null, the root list will be empty since it has been
- // cleared above.
-
- // get the AndroidTargetData from the project
- IAndroidTarget target = null;
- AndroidTargetData data = null;
-
- target = Sdk.getCurrent().getTarget(project);
- if (target == null) {
- // A project should have a target. The target can be missing if the project
- // is an old project for which a target hasn't been affected or if the
- // target no longer exists in this SDK. Simply log the error and dismiss.
-
- AdtPlugin.log(IStatus.INFO,
- "NewXmlFile wizard: no platform target for project %s", //$NON-NLS-1$
- project.getName());
- continue;
- } else {
- data = Sdk.getCurrent().getTargetData(target);
-
- if (data == null) {
- // We should have both a target and its data.
- // However if the wizard is invoked whilst the platform is still being
- // loaded we can end up in a weird case where we have a target but it
- // doesn't have any data yet.
- // Lets log a warning and silently ignore this root.
-
- AdtPlugin.log(IStatus.INFO,
- "NewXmlFile wizard: no data for target %s, project %s", //$NON-NLS-1$
- target.getName(), project.getName());
- continue;
- }
- }
-
- IDescriptorProvider provider = data.getDescriptorProvider((Integer)rootSeed);
- ElementDescriptor descriptor = provider.getDescriptor();
- if (descriptor != null) {
- HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
- initRootElementDescriptor(roots, descriptor, visited);
- }
-
- // Sort alphabetically.
- Collections.sort(roots);
- }
- }
- }
-
- /**
- * Helper method to recursively insert all XML names for the given {@link ElementDescriptor}
- * into the roots array list. Keeps track of visited nodes to avoid infinite recursion.
- * Also avoids inserting the top {@link DocumentDescriptor} which is generally synthetic
- * and not a valid root element.
- */
- private void initRootElementDescriptor(ArrayList<String> roots,
- ElementDescriptor desc, HashSet<ElementDescriptor> visited) {
- if (!(desc instanceof DocumentDescriptor)) {
- String xmlName = desc.getXmlName();
- if (xmlName != null && xmlName.length() > 0) {
- roots.add(xmlName);
- }
- }
-
- visited.add(desc);
-
- for (ElementDescriptor child : desc.getChildren()) {
- if (!visited.contains(child)) {
- initRootElementDescriptor(roots, child, visited);
- }
- }
- }
-
- /**
- * Changes mProject to the given new project and update the UI accordingly.
- * <p/>
- * Note that this does not check if the new project is the same as the current one
- * on purpose, which allows a project to be updated when its target has changed or
- * when targets are loaded in the background.
- */
- private void changeProject(IProject newProject) {
- mValues.project = newProject;
-
- // enable types based on new API level
- updateAvailableTypes();
- initialSelectType();
-
- // update the folder name based on API level
- updateFolderPath(mValues.type);
-
- // update the Type with the new descriptors.
- initializeRootValues();
-
- // update the combo
- updateRootCombo(mValues.type);
-
- validatePage();
- }
-
- private void onSelectType(TypeInfo type) {
- // Do nothing if this is an internal modification or if the widget has been
- // deselected.
- if (mInternalTypeUpdate) {
- return;
- }
-
- mValues.type = type;
-
- if (type == null) {
- return;
- }
-
- // update the combo
- updateRootCombo(type);
-
- // update the folder path
- updateFolderPath(type);
-
- validatePage();
- }
-
- /** Updates the selected type in the type dropdown control */
- private void setSelectedType(TypeInfo type) {
- TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
- if (types != null) {
- for (int i = 0, n = types.length; i < n; i++) {
- if (types[i] == type) {
- mTypeCombo.select(i);
- break;
- }
- }
- }
- }
-
- /** Returns the selected type in the type dropdown control */
- private TypeInfo getSelectedType() {
- int index = mTypeCombo.getSelectionIndex();
- if (index != -1) {
- TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
- return types[index];
- }
-
- return null;
- }
-
- /** Returns the selected index in the type dropdown control */
- private int getTypeComboIndex(TypeInfo type) {
- TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
- for (int i = 0, n = types.length; i < n; i++) {
- if (type == types[i]) {
- return i;
- }
- }
-
- return -1;
- }
-
- /** Updates the folder path to reflect the given type */
- private void updateFolderPath(TypeInfo type) {
- String wsFolderPath = mValues.folderPath;
- String newPath = null;
- FolderConfiguration config = mValues.configuration;
- ResourceQualifier qual = config.getInvalidQualifier();
- if (qual == null) {
- // The configuration is valid. Reformat the folder path using the canonical
- // value from the configuration.
- newPath = RES_FOLDER_ABS + config.getFolderName(type.getResFolderType());
- } else {
- // The configuration is invalid. We still update the path but this time
- // do it manually on the string.
- if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
- wsFolderPath = wsFolderPath.replaceFirst(
- "^(" + RES_FOLDER_ABS +")[^-]*(.*)", //$NON-NLS-1$ //$NON-NLS-2$
- "\\1" + type.getResFolderName() + "\\2"); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- newPath = RES_FOLDER_ABS + config.getFolderName(type.getResFolderType());
- }
- }
-
- if (newPath != null && !newPath.equals(wsFolderPath)) {
- mValues.folderPath = newPath;
- }
- }
-
- /**
- * Helper method that fills the values of the "root element" combo box based
- * on the currently selected type radio button. Also disables the combo is there's
- * only one choice. Always select the first root element for the given type.
- *
- * @param type The currently selected {@link TypeInfo}, or null
- */
- private void updateRootCombo(TypeInfo type) {
- IBaseLabelProvider labelProvider = new ColumnLabelProvider() {
- @Override
- public Image getImage(Object element) {
- return IconFactory.getInstance().getIcon(element.toString());
- }
- };
- mRootTableViewer.setContentProvider(new ArrayContentProvider());
- mRootTableViewer.setLabelProvider(labelProvider);
-
- if (type != null) {
- // get the list of roots. The list can be empty but not null.
- ArrayList<String> roots = type.getRoots();
- mRootTableViewer.setInput(roots.toArray());
-
- int index = 0; // default is to select the first one
- String defaultRoot = type.getDefaultRoot(mValues.project);
- if (defaultRoot != null) {
- index = roots.indexOf(defaultRoot);
- }
- mRootTable.select(index < 0 ? 0 : index);
- mRootTable.showSelection();
- }
- }
-
- /**
- * Helper method to select the current type in the type dropdown
- *
- * @param type The TypeInfo matching the radio button to selected or null to deselect them all.
- */
- private void selectType(TypeInfo type) {
- mInternalTypeUpdate = true;
- mValues.type = type;
- if (type == null) {
- if (mTypeCombo.getSelectionIndex() != -1) {
- mTypeCombo.deselect(mTypeCombo.getSelectionIndex());
- }
- } else {
- setSelectedType(type);
- }
- updateRootCombo(type);
- mInternalTypeUpdate = false;
- }
-
- /**
- * Add the available types in the type combobox, based on whether they are available
- * for the current SDK.
- * <p/>
- * A type is available either if:
- * - if mProject is null, API level 1 is considered valid
- * - if mProject is !null, the project->target->API must be >= to the type's API level.
- */
- private void updateAvailableTypes() {
- IProject project = mValues.project;
- IAndroidTarget target = project != null ? Sdk.getCurrent().getTarget(project) : null;
- int currentApiLevel = 1;
- if (target != null) {
- currentApiLevel = target.getVersion().getApiLevel();
- }
-
- List<String> items = new ArrayList<String>(sTypes.length);
- List<TypeInfo> types = new ArrayList<TypeInfo>(sTypes.length);
- for (int i = 0, n = sTypes.length; i < n; i++) {
- TypeInfo type = sTypes[i];
- if (type.getTargetApiLevel() <= currentApiLevel) {
- items.add(type.getUiName());
- types.add(type);
- }
- }
- mTypeCombo.setItems(items.toArray(new String[items.size()]));
- mTypeCombo.setData(types.toArray(new TypeInfo[types.size()]));
- }
-
- /**
- * Validates the fields, displays errors and warnings.
- * Enables the finish button if there are no errors.
- */
- private void validatePage() {
- String error = null;
- String warning = null;
-
- // -- validate type
- TypeInfo type = mValues.type;
- if (error == null) {
- if (type == null) {
- error = "One of the types must be selected (e.g. layout, values, etc.)";
- }
- }
-
- // -- validate project
- if (mValues.project == null) {
- error = "Please select an Android project.";
- }
-
- // -- validate type API level
- if (error == null) {
- IAndroidTarget target = Sdk.getCurrent().getTarget(mValues.project);
- int currentApiLevel = 1;
- if (target != null) {
- currentApiLevel = target.getVersion().getApiLevel();
- }
-
- assert type != null;
- if (type.getTargetApiLevel() > currentApiLevel) {
- error = "The API level of the selected type (e.g. AppWidget, etc.) is not " +
- "compatible with the API level of the project.";
- }
- }
-
- // -- validate filename
- if (error == null) {
- String fileName = mValues.getFileName();
- assert type != null;
- ResourceFolderType folderType = type.getResFolderType();
- error = ResourceNameValidator.create(true, folderType).isValid(fileName);
- }
-
- // -- validate destination file doesn't exist
- if (error == null) {
- IFile file = mValues.getDestinationFile();
- if (file != null && file.exists()) {
- warning = "The destination file already exists";
- }
- }
-
- // -- update UI & enable finish if there's no error
- setPageComplete(error == null);
- if (error != null) {
- setMessage(error, IMessageProvider.ERROR);
- } else if (warning != null) {
- setMessage(warning, IMessageProvider.WARNING);
- } else {
- setErrorMessage(null);
- setMessage(null);
- }
- }
-
- /**
- * Returns the {@link TypeInfo} for the given {@link ResourceFolderType}, or null if
- * not found
- *
- * @param folderType the {@link ResourceFolderType} to look for
- * @return the corresponding {@link TypeInfo}
- */
- static TypeInfo getTypeInfo(ResourceFolderType folderType) {
- for (TypeInfo typeInfo : sTypes) {
- if (typeInfo.getResFolderType() == folderType) {
- return typeInfo;
- }
- }
-
- return null;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
deleted file mode 100644
index 16cd7b355..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2008 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.newxmlfile;
-
-import static com.android.SdkConstants.FQCN_GRID_LAYOUT;
-import static com.android.SdkConstants.GRID_LAYOUT;
-
-import com.android.SdkConstants;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-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.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-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.RenderPreviewManager;
-import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
-import com.android.ide.eclipse.adt.internal.project.SupportLibraryHelper;
-import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
-import com.android.resources.ResourceFolderType;
-import com.android.utils.Pair;
-
-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.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PartInitException;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * The "New Android XML File Wizard" provides the ability to create skeleton XML
- * resources files for Android projects.
- * <p/>
- * The wizard has one page, {@link NewXmlFileCreationPage}, used to select the project,
- * the resource folder, resource type and file name. It then creates the XML file.
- */
-public class NewXmlFileWizard extends Wizard implements INewWizard {
- /** The XML header to write at the top of the XML file */
- public static final String XML_HEADER_LINE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; //$NON-NLS-1$
-
- private static final String PROJECT_LOGO_LARGE = "android-64"; //$NON-NLS-1$
-
- protected static final String MAIN_PAGE_NAME = "newAndroidXmlFilePage"; //$NON-NLS-1$
-
- private NewXmlFileCreationPage mMainPage;
- private ChooseConfigurationPage mConfigPage;
- private Values mValues;
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- setHelpAvailable(false); // TODO have help
- setWindowTitle("New Android XML File");
- setImageDescriptor();
-
- mValues = new Values();
- mMainPage = createMainPage(mValues);
- mMainPage.setTitle("New Android XML File");
- mMainPage.setDescription("Creates a new Android XML file.");
- mMainPage.setInitialSelection(selection);
-
- mConfigPage = new ChooseConfigurationPage(mValues);
-
- // Trigger a check to see if the SDK needs to be reloaded (which will
- // invoke onSdkLoaded asynchronously as needed).
- AdtPlugin.getDefault().refreshSdk();
- }
-
- /**
- * Creates the wizard page.
- * <p/>
- * Please do NOT override this method.
- * <p/>
- * This is protected so that it can be overridden by unit tests.
- * However the contract of this class is private and NO ATTEMPT will be made
- * to maintain compatibility between different versions of the plugin.
- */
- protected NewXmlFileCreationPage createMainPage(NewXmlFileWizard.Values values) {
- return new NewXmlFileCreationPage(MAIN_PAGE_NAME, values);
- }
-
- // -- Methods inherited from org.eclipse.jface.wizard.Wizard --
- //
- // The Wizard class implements most defaults and boilerplate code needed by
- // IWizard
-
- /**
- * Adds pages to this wizard.
- */
- @Override
- public void addPages() {
- addPage(mMainPage);
- addPage(mConfigPage);
-
- }
-
- /**
- * Performs any actions appropriate in response to the user having pressed
- * the Finish button, or refuse if finishing now is not permitted: here, it
- * actually creates the workspace project and then switch to the Java
- * perspective.
- *
- * @return True
- */
- @Override
- public boolean performFinish() {
- final Pair<IFile, IRegion> created = createXmlFile();
- if (created == null) {
- return false;
- } else {
- // Open the file
- // This has to be delayed in order for focus handling to work correctly
- AdtPlugin.getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- IFile file = created.getFirst();
- IRegion region = created.getSecond();
- try {
- IEditorPart editor = AdtPlugin.openFile(file, null,
- false /*showEditorTab*/);
- if (editor instanceof AndroidXmlEditor) {
- final AndroidXmlEditor xmlEditor = (AndroidXmlEditor)editor;
- if (!xmlEditor.hasMultiplePages()) {
- xmlEditor.show(region.getOffset(), region.getLength(),
- true /* showEditorTab */);
- }
- }
- } catch (PartInitException e) {
- AdtPlugin.log(e, "Failed to create %1$s: missing type", //$NON-NLS-1$
- file.getFullPath().toString());
- }
- }});
-
- return true;
- }
- }
-
- // -- Custom Methods --
-
- private Pair<IFile, IRegion> createXmlFile() {
- IFile file = mValues.getDestinationFile();
- TypeInfo type = mValues.type;
- if (type == null) {
- // this is not expected to happen
- String name = file.getFullPath().toString();
- AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing type", name); //$NON-NLS-1$
- return null;
- }
- String xmlns = type.getXmlns();
- String root = mMainPage.getRootElement();
- if (root == null) {
- // this is not expected to happen
- AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing root element", //$NON-NLS-1$
- file.toString());
- return null;
- }
-
- String attrs = type.getDefaultAttrs(mValues.project, root);
- String child = type.getChild(mValues.project, root);
- return createXmlFile(file, xmlns, root, attrs, child, type.getResFolderType());
- }
-
- /** Creates a new file using the given root element, namespace and root attributes */
- private static Pair<IFile, IRegion> createXmlFile(IFile file, String xmlns,
- String root, String rootAttributes, String child, ResourceFolderType folderType) {
- String name = file.getFullPath().toString();
- boolean need_delete = false;
-
- if (file.exists()) {
- if (!AdtPlugin.displayPrompt("New Android XML File",
- String.format("Do you want to overwrite the file %1$s ?", name))) {
- // abort if user selects cancel.
- return null;
- }
- need_delete = true;
- } else {
- AdtUtils.createWsParentDirectory(file.getParent());
- }
-
- StringBuilder sb = new StringBuilder(XML_HEADER_LINE);
-
- if (folderType == ResourceFolderType.LAYOUT && root.equals(GRID_LAYOUT)) {
- IProject project = file.getParent().getProject();
- int minSdk = ManifestInfo.get(project).getMinSdkVersion();
- if (minSdk < 14) {
- root = SupportLibraryHelper.getTagFor(project, FQCN_GRID_LAYOUT);
- if (root.equals(FQCN_GRID_LAYOUT)) {
- root = GRID_LAYOUT;
- }
- }
- }
-
- sb.append('<').append(root);
- if (xmlns != null) {
- sb.append('\n').append(" xmlns:android=\"").append(xmlns).append('"'); //$NON-NLS-1$
- }
-
- if (rootAttributes != null) {
- sb.append("\n "); //$NON-NLS-1$
- sb.append(rootAttributes.replace("\n", "\n ")); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- sb.append(">\n"); //$NON-NLS-1$
-
- if (child != null) {
- sb.append(child);
- }
-
- boolean autoFormat = AdtPrefs.getPrefs().getUseCustomXmlFormatter();
-
- // Insert an indented caret. Since the markup here will be reformatted, we need to
- // insert text tokens that the formatter will preserve, which we can then turn back
- // into indentation and a caret offset:
- final String indentToken = "${indent}"; //$NON-NLS-1$
- final String caretToken = "${caret}"; //$NON-NLS-1$
- sb.append(indentToken);
- sb.append(caretToken);
- if (!autoFormat) {
- sb.append('\n');
- }
-
- sb.append("</").append(root).append(">\n"); //$NON-NLS-1$ //$NON-NLS-2$
-
- EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
- String fileContents;
- if (!autoFormat) {
- fileContents = sb.toString();
- } else {
- XmlFormatStyle style = EclipseXmlPrettyPrinter.getForFolderType(folderType);
- fileContents = EclipseXmlPrettyPrinter.prettyPrint(sb.toString(), formatPrefs,
- style, null /*lineSeparator*/);
- }
-
- // Remove marker tokens and replace them with whitespace
- fileContents = fileContents.replace(indentToken, formatPrefs.getOneIndentUnit());
- int caretOffset = fileContents.indexOf(caretToken);
- if (caretOffset != -1) {
- fileContents = fileContents.replace(caretToken, ""); //$NON-NLS-1$
- }
-
- String error = null;
- try {
- byte[] buf = fileContents.getBytes("UTF8"); //$NON-NLS-1$
- InputStream stream = new ByteArrayInputStream(buf);
- if (need_delete) {
- file.delete(IResource.KEEP_HISTORY | IResource.FORCE, null /*monitor*/);
- }
- file.create(stream, true /*force*/, null /*progress*/);
- IRegion region = caretOffset != -1 ? new Region(caretOffset, 0) : null;
-
- // If you introduced a new locale, or new screen variations etc, ensure that
- // the list of render previews is updated if necessary
- if (file.getParent().getName().indexOf('-') != -1
- && (folderType == ResourceFolderType.LAYOUT
- || folderType == ResourceFolderType.VALUES)) {
- RenderPreviewManager.bumpRevision();
- }
-
- return Pair.of(file, region);
- } catch (UnsupportedEncodingException e) {
- error = e.getMessage();
- } catch (CoreException e) {
- error = e.getMessage();
- }
-
- error = String.format("Failed to generate %1$s: %2$s", name, error);
- AdtPlugin.displayError("New Android XML File", error);
- return null;
- }
-
- /**
- * Returns true if the New XML Wizard can create new files of the given
- * {@link ResourceFolderType}
- *
- * @param folderType the folder type to create a file for
- * @return true if this wizard can create new files for the given folder type
- */
- public static boolean canCreateXmlFile(ResourceFolderType folderType) {
- TypeInfo typeInfo = NewXmlFileCreationPage.getTypeInfo(folderType);
- return typeInfo != null && (typeInfo.getDefaultRoot(null /*project*/) != null ||
- typeInfo.getRootSeed() instanceof String);
- }
-
- /**
- * Creates a new XML file using the template according to the given folder type
- *
- * @param project the project to create the file in
- * @param file the file to be created
- * @param folderType the type of folder to look up a template for
- * @return the created file
- */
- public static Pair<IFile, IRegion> createXmlFile(IProject project, IFile file,
- ResourceFolderType folderType) {
- TypeInfo type = NewXmlFileCreationPage.getTypeInfo(folderType);
- String xmlns = type.getXmlns();
- String root = type.getDefaultRoot(project);
- if (root == null) {
- root = type.getRootSeed().toString();
- }
- String attrs = type.getDefaultAttrs(project, root);
- return createXmlFile(file, xmlns, root, attrs, null, folderType);
- }
-
- /**
- * Returns an image descriptor for the wizard logo.
- */
- private void setImageDescriptor() {
- ImageDescriptor desc = IconFactory.getInstance().getImageDescriptor(PROJECT_LOGO_LARGE);
- setDefaultPageImageDescriptor(desc);
- }
-
- /**
- * Specific New XML File wizard tied to the {@link ResourceFolderType#LAYOUT} type
- */
- public static class NewLayoutWizard extends NewXmlFileWizard {
- /** Creates a new {@link NewLayoutWizard} */
- public NewLayoutWizard() {
- }
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- super.init(workbench, selection);
- setWindowTitle("New Android Layout XML File");
- super.mMainPage.setTitle("New Android Layout XML File");
- super.mMainPage.setDescription("Creates a new Android Layout XML file.");
- super.mMainPage.setInitialFolderType(ResourceFolderType.LAYOUT);
- }
- }
-
- /**
- * Specific New XML File wizard tied to the {@link ResourceFolderType#VALUES} type
- */
- public static class NewValuesWizard extends NewXmlFileWizard {
- /** Creates a new {@link NewValuesWizard} */
- public NewValuesWizard() {
- }
-
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- super.init(workbench, selection);
- setWindowTitle("New Android Values XML File");
- super.mMainPage.setTitle("New Android Values XML File");
- super.mMainPage.setDescription("Creates a new Android Values XML file.");
- super.mMainPage.setInitialFolderType(ResourceFolderType.VALUES);
- }
- }
-
- /** Value object which holds the current state of the wizard pages */
- public static class Values {
- /** The currently selected project, or null */
- public IProject project;
- /** The root name of the XML file to create, or null */
- public String name;
- /** The type of XML file to create */
- public TypeInfo type;
- /** The path within the project to create the new file in */
- public String folderPath;
- /** The currently chosen configuration */
- public FolderConfiguration configuration = new FolderConfiguration();
-
- /**
- * Returns the destination filename or an empty string.
- *
- * @return the filename, never null.
- */
- public String getFileName() {
- String fileName;
- if (name == null) {
- fileName = ""; //$NON-NLS-1$
- } else {
- fileName = name.trim();
- if (fileName.length() > 0 && fileName.indexOf('.') == -1) {
- fileName = fileName + SdkConstants.DOT_XML;
- }
- }
-
- return fileName;
- }
-
- /**
- * Returns a {@link IFile} for the destination file.
- * <p/>
- * Returns null if the project, filename or folder are invalid and the
- * destination file cannot be determined.
- * <p/>
- * The {@link IFile} is a resource. There might or might not be an
- * actual real file.
- *
- * @return an {@link IFile} for the destination file
- */
- public IFile getDestinationFile() {
- String fileName = getFileName();
- if (project != null && folderPath != null && folderPath.length() > 0
- && fileName.length() > 0) {
- IPath dest = new Path(folderPath).append(fileName);
- IFile file = project.getFile(dest);
- return file;
- }
- return null;
- }
- }
-}
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) {
- }
-}