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;
}
}