aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java494
1 files changed, 494 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
new file mode 100644
index 000000000..c66458fc9
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
@@ -0,0 +1,494 @@
+/*
+ * 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.launch;
+
+import com.android.ide.common.xml.ManifestData;
+import com.android.ide.common.xml.ManifestData.Activity;
+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.ProjectChooserHelper;
+import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.IProjectChooserFilter;
+import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.NonLibraryProjectOnlyFilter;
+
+import org.eclipse.core.resources.IProject;
+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.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+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.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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.ArrayList;
+
+/**
+ * Class for the main launch configuration tab.
+ */
+public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab {
+
+ /**
+ *
+ */
+ public static final String LAUNCH_TAB_IMAGE = "mainLaunchTab"; //$NON-NLS-1$
+
+ protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ protected Text mProjText;
+ private Button mProjButton;
+
+ private Combo mActivityCombo;
+ private final ArrayList<Activity> mActivities = new ArrayList<Activity>();
+
+ private WidgetListener mListener = new WidgetListener();
+
+ private Button mDefaultActionButton;
+ private Button mActivityActionButton;
+ private Button mDoNothingActionButton;
+ private int mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
+
+ private ProjectChooserHelper mProjectChooserHelper;
+
+ /**
+ * A listener which handles widget change events for the controls in this
+ * tab.
+ */
+ private class WidgetListener implements ModifyListener, SelectionListener {
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ IProject project = checkParameters();
+ loadActivities(project);
+ setDirty(true);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {/* do nothing */
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Object source = e.getSource();
+ if (source == mProjButton) {
+ handleProjectButtonSelected();
+ } else {
+ checkParameters();
+ }
+ }
+ }
+
+ public MainLaunchConfigTab() {
+ }
+
+ protected IProjectChooserFilter getProjectFilter() {
+ return new NonLibraryProjectOnlyFilter();
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ mProjectChooserHelper = new ProjectChooserHelper(parent.getShell(), getProjectFilter());
+
+ Font font = parent.getFont();
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+ GridLayout topLayout = new GridLayout();
+ topLayout.verticalSpacing = 0;
+ comp.setLayout(topLayout);
+ comp.setFont(font);
+ createProjectEditor(comp);
+ createVerticalSpacer(comp, 1);
+
+ // create the combo for the activity chooser
+ Group group = new Group(comp, SWT.NONE);
+ group.setText("Launch Action:");
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ group.setLayoutData(gd);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setFont(font);
+
+ mDefaultActionButton = new Button(group, SWT.RADIO);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ mDefaultActionButton.setLayoutData(gd);
+ mDefaultActionButton.setText("Launch Default Activity");
+ mDefaultActionButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // event are received for both selection and deselection, so we only process
+ // the selection event to avoid doing it twice.
+ if (mDefaultActionButton.getSelection() == true) {
+ mLaunchAction = LaunchConfigDelegate.ACTION_DEFAULT;
+ mActivityCombo.setEnabled(false);
+ checkParameters();
+ }
+ }
+ });
+
+ mActivityActionButton = new Button(group, SWT.RADIO);
+ mActivityActionButton.setText("Launch:");
+ mActivityActionButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // event are received for both selection and deselection, so we only process
+ // the selection event to avoid doing it twice.
+ if (mActivityActionButton.getSelection() == true) {
+ mLaunchAction = LaunchConfigDelegate.ACTION_ACTIVITY;
+ mActivityCombo.setEnabled(true);
+ checkParameters();
+ }
+ }
+ });
+
+ mActivityCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ mActivityCombo.setLayoutData(gd);
+ mActivityCombo.clearSelection();
+ mActivityCombo.setEnabled(false);
+ mActivityCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ checkParameters();
+ }
+ });
+
+ mDoNothingActionButton = new Button(group, SWT.RADIO);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ mDoNothingActionButton.setLayoutData(gd);
+ mDoNothingActionButton.setText("Do Nothing");
+ mDoNothingActionButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // event are received for both selection and deselection, so we only process
+ // the selection event to avoid doing it twice.
+ if (mDoNothingActionButton.getSelection() == true) {
+ mLaunchAction = LaunchConfigDelegate.ACTION_DO_NOTHING;
+ mActivityCombo.setEnabled(false);
+ checkParameters();
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public String getName() {
+ return "Android";
+ }
+
+ @Override
+ public Image getImage() {
+ return IconFactory.getInstance().getIcon(LAUNCH_TAB_IMAGE);
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, mProjText.getText());
+ configuration.setAttribute(
+ IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, true);
+
+ // add the launch mode
+ configuration.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION, mLaunchAction);
+
+ // add the activity
+ int selection = mActivityCombo.getSelectionIndex();
+ if (mActivities != null && selection >=0 && selection < mActivities.size()) {
+ configuration.setAttribute(LaunchConfigDelegate.ATTR_ACTIVITY,
+ mActivities.get(selection).getName());
+ }
+
+ // link the project and the launch config.
+ mapResources(configuration);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
+ LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION);
+ }
+
+ /**
+ * Creates the widgets for specifying a main type.
+ *
+ * @param parent the parent composite
+ */
+ protected void createProjectEditor(Composite parent) {
+ Font font = parent.getFont();
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Project:");
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ group.setLayoutData(gd);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setFont(font);
+ mProjText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ mProjText.setLayoutData(gd);
+ mProjText.setFont(font);
+ mProjText.addModifyListener(mListener);
+ mProjButton = createPushButton(group, "Browse...", null);
+ mProjButton.addSelectionListener(mListener);
+ }
+
+ /**
+ * returns the default listener from this class. For all subclasses this
+ * listener will only provide the functi Jaonality of updating the current
+ * tab
+ *
+ * @return a widget listener
+ */
+ protected WidgetListener getDefaultListener() {
+ return mListener;
+ }
+
+ /**
+ * Return the {@link IJavaProject} corresponding to the project name in the project
+ * name text field, or null if the text does not match a project name.
+ * @param javaModel the Java Model object corresponding for the current workspace root.
+ * @return a IJavaProject object or null.
+ */
+ protected IJavaProject getJavaProject(IJavaModel javaModel) {
+ String projectName = mProjText.getText().trim();
+ if (projectName.length() < 1) {
+ return null;
+ }
+ return javaModel.getJavaProject(projectName);
+ }
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides
+ * context for the main type, allowing the user to key a main type name, or
+ * constraining the search for main types to the specified project.
+ */
+ protected void handleProjectButtonSelected() {
+ IJavaProject javaProject = mProjectChooserHelper.chooseJavaProject(
+ mProjText.getText().trim(),
+ "Please select a project to launch");
+ if (javaProject == null) {
+ return;
+ }// end if
+ String projectName = javaProject.getElementName();
+ mProjText.setText(projectName);
+
+ // get the list of activities and fill the combo
+ IProject project = javaProject.getProject();
+ loadActivities(project);
+ }// end handle selected
+
+ /**
+ * Initializes this tab's controls with values from the given
+ * launch configuration. This method is called when
+ * a configuration is selected to view or edit, after this
+ * tab's control has been created.
+ *
+ * @param config launch configuration
+ *
+ * @see ILaunchConfigurationTab
+ */
+ @Override
+ public void initializeFrom(ILaunchConfiguration config) {
+ String projectName = EMPTY_STRING;
+ try {
+ projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ EMPTY_STRING);
+ }// end try
+ catch (CoreException ce) {
+ }
+ mProjText.setText(projectName);
+
+ IProject proj = mProjectChooserHelper.getAndroidProject(projectName);
+ loadActivities(proj);
+
+ // load the launch action.
+ mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
+ try {
+ mLaunchAction = config.getAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
+ mLaunchAction);
+ } catch (CoreException e) {
+ // nothing to be done really. launchAction will keep its default value.
+ }
+
+ mDefaultActionButton.setSelection(mLaunchAction == LaunchConfigDelegate.ACTION_DEFAULT);
+ mActivityActionButton.setSelection(mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY);
+ mDoNothingActionButton.setSelection(
+ mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING);
+
+ // now look for the activity and load it if present, otherwise, revert
+ // to the current one.
+ String activityName = EMPTY_STRING;
+ try {
+ activityName = config.getAttribute(LaunchConfigDelegate.ATTR_ACTIVITY, EMPTY_STRING);
+ }// end try
+ catch (CoreException ce) {
+ // nothing to be done really. activityName will stay empty
+ }
+
+ if (mLaunchAction != LaunchConfigDelegate.ACTION_ACTIVITY) {
+ mActivityCombo.setEnabled(false);
+ mActivityCombo.clearSelection();
+ } else {
+ mActivityCombo.setEnabled(true);
+ if (activityName == null || activityName.equals(EMPTY_STRING)) {
+ mActivityCombo.clearSelection();
+ } else if (mActivities != null && mActivities.size() > 0) {
+ // look for the name of the activity in the combo.
+ boolean found = false;
+ for (int i = 0 ; i < mActivities.size() ; i++) {
+ if (activityName.equals(mActivities.get(i).getName())) {
+ found = true;
+ mActivityCombo.select(i);
+ break;
+ }
+ }
+
+ // if we haven't found a matching activity we clear the combo selection
+ if (found == false) {
+ mActivityCombo.clearSelection();
+ }
+ }
+ }
+ }
+
+ /**
+ * Associates the launch config and the project. This allows Eclipse to delete the launch
+ * config when the project is deleted.
+ *
+ * @param config the launch config working copy.
+ */
+ protected void mapResources(ILaunchConfigurationWorkingCopy config) {
+ // get the java model
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IJavaModel javaModel = JavaCore.create(workspaceRoot);
+
+ // get the IJavaProject described by the text field.
+ IJavaProject javaProject = getJavaProject(javaModel);
+ IResource[] resources = null;
+ if (javaProject != null) {
+ resources = AndroidLaunchController.getResourcesToMap(javaProject.getProject());
+ }
+ config.setMappedResources(resources);
+ }
+
+ /**
+ * Loads the ui with the activities of the specified project, and stores the
+ * activities in <code>mActivities</code>.
+ * <p/>
+ * First activity is selected by default if present.
+ *
+ * @param project The project to load the activities from.
+ */
+ private void loadActivities(IProject project) {
+ if (project != null) {
+ // parse the manifest for the list of activities.
+ ManifestData manifestData = AndroidManifestHelper.parseForData(project);
+ if (manifestData != null) {
+ Activity[] activities = manifestData.getActivities();
+
+ mActivities.clear();
+ mActivityCombo.removeAll();
+
+ for (Activity activity : activities) {
+ if (activity.isExported() && activity.hasAction()) {
+ mActivities.add(activity);
+ mActivityCombo.add(activity.getName());
+ }
+ }
+
+ if (mActivities.size() > 0) {
+ if (mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY) {
+ mActivityCombo.setEnabled(true);
+ }
+ } else {
+ mActivityCombo.setEnabled(false);
+ }
+
+ // the selection will be set when we update the ui from the current
+ // config object.
+ mActivityCombo.clearSelection();
+
+ return;
+ }
+ }
+
+ // if we reach this point, either project is null, or we got an exception during
+ // the parsing. In either case, we empty the activity list.
+ mActivityCombo.removeAll();
+ mActivities.clear();
+ }
+
+ /**
+ * Checks the parameters for correctness, and update the error message and buttons.
+ * @return the current IProject of this launch config.
+ */
+ private IProject checkParameters() {
+ try {
+ //test the project name first!
+ String text = mProjText.getText();
+ if (text.length() == 0) {
+ setErrorMessage("Project Name is required!");
+ } 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);
+ } else {
+ setErrorMessage(String.format("There is no android project named '%1$s'",
+ text));
+ }
+
+ return found;
+ }
+ } finally {
+ updateLaunchConfigurationDialog();
+ }
+
+ return null;
+ }
+}