package thahn.java.agui.ide.eclipse.launch; import java.util.ArrayList; import org.eclipse.core.resources.IProject; 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.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 thahn.java.agui.app.Activity; import thahn.java.agui.ide.eclipse.project.IconFactory; import thahn.java.agui.ide.eclipse.project.ProjectChooserHelper; import thahn.java.agui.ide.eclipse.project.ProjectChooserHelper.IProjectChooserFilter; import thahn.java.agui.ide.eclipse.project.ProjectChooserHelper.NonLibraryProjectOnlyFilter; import thahn.java.agui.utils.Log; public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab { public static final String TAG = "MainLaunchConfigTab"; /** * */ 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) { Log.d(TAG, "createControl"); 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 "Agui"; } @Override public Image getImage() { return IconFactory.getInstance().getIcon(LAUNCH_TAB_IMAGE); } @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { Log.d(TAG, "performApply"); 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) { Log.d(TAG, "initializeFrom"); 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.getAguiProject(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.getAguiProjects(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 agui project named '%1$s'", text)); } return found; } } finally { updateLaunchConfigurationDialog(); } return null; } }