Fields Summary |
---|
private static final TypeInfo[] | sTypesTypeInfo, information for each "type" of file that can be created. |
static final int | NUM_COLNumber of columns in the grid layout |
private static final String | RES_FOLDER_ABSAbsolute destination folder root, e.g. "/res/" |
private static final String | RES_FOLDER_RELRelative destination folder root, e.g. "res/" |
private org.eclipse.core.resources.IProject | mProject |
private org.eclipse.swt.widgets.Text | mProjectTextField |
private org.eclipse.swt.widgets.Button | mProjectBrowseButton |
private org.eclipse.swt.widgets.Text | mFileNameTextField |
private org.eclipse.swt.widgets.Text | mWsFolderPathTextField |
private org.eclipse.swt.widgets.Combo | mRootElementCombo |
private org.eclipse.jface.viewers.IStructuredSelection | mInitialSelection |
private com.android.ide.eclipse.adt.ui.ConfigurationSelector | mConfigSelector |
private com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration | mTempConfig |
private boolean | mInternalWsFolderPathUpdate |
private boolean | mInternalTypeUpdate |
private boolean | mInternalConfigSelectorUpdate |
private com.android.ide.eclipse.common.project.ProjectChooserHelper | mProjectChooserHelper |
private com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener | mSdkTargetChangeListener |
private TypeInfo | mCurrentTypeInfo |
Methods Summary |
---|
private void | changeProject(org.eclipse.core.resources.IProject newProject)Changes mProject to the given new project and update the UI accordingly.
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.
mProject = newProject;
// enable types based on new API level
enableTypesBasedOnApi();
// update the Type with the new descriptors.
initializeRootValues();
// update the combo
updateRootCombo(getSelectedType());
validatePage();
|
public void | createControl(org.eclipse.swt.widgets.Composite parent)Called by the parent Wizard to create the UI for this Wizard Page.
{@inheritDoc}
Composite composite = new Composite(parent, SWT.NULL);
composite.setFont(parent.getFont());
initializeDialogUnits(parent);
composite.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
createProjectGroup(composite);
createTypeGroup(composite);
createRootGroup(composite);
// Show description the first time
setErrorMessage(null);
setMessage(null);
setControl(composite);
// Update state the first time
initializeFromSelection(mInitialSelection);
initializeRootValues();
enableTypesBasedOnApi();
if (mCurrentTypeInfo != null) {
updateRootCombo(mCurrentTypeInfo);
}
installTargetChangeListener();
validatePage();
|
private void | createProjectGroup(org.eclipse.swt.widgets.Composite parent)Creates the project & filename fields.
The parent must be a GridLayout with NUM_COL colums.
int col = 0;
// project name
String tooltip = "The Android Project where the new resource file will be created.";
Label label = new Label(parent, SWT.NONE);
label.setText("Project");
label.setToolTipText(tooltip);
++col;
mProjectTextField = new Text(parent, SWT.BORDER);
mProjectTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mProjectTextField.setToolTipText(tooltip);
mProjectTextField.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
onProjectFieldUpdated();
}
});
++col;
mProjectBrowseButton = new Button(parent, SWT.NONE);
mProjectBrowseButton.setText("Browse...");
mProjectBrowseButton.setToolTipText("Allows you to select the Android project to modify.");
mProjectBrowseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onProjectBrowse();
}
});
mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
++col;
col = padWithEmptyCells(parent, col);
// file name
tooltip = "The name of the resource file to create.";
label = new Label(parent, SWT.NONE);
label.setText("File");
label.setToolTipText(tooltip);
++col;
mFileNameTextField = new Text(parent, SWT.BORDER);
mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mFileNameTextField.setToolTipText(tooltip);
mFileNameTextField.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
validatePage();
}
});
++col;
padWithEmptyCells(parent, col);
|
private void | createRootGroup(org.eclipse.swt.widgets.Composite parent)Creates the root element combo.
The parent must be a GridLayout with NUM_COL colums.
// separator
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
// label before the root combo
String tooltip = "The root element to create in the XML file.";
label = new Label(parent, SWT.NONE);
label.setText("Select the root element for the XML file:");
label.setLayoutData(newGridData(NUM_COL));
label.setToolTipText(tooltip);
// root combo
emptyCell(parent);
mRootElementCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
mRootElementCombo.setEnabled(false);
mRootElementCombo.select(0);
mRootElementCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mRootElementCombo.setToolTipText(tooltip);
padWithEmptyCells(parent, 2);
|
private void | createTypeGroup(org.eclipse.swt.widgets.Composite parent)Creates the type field, {@link ConfigurationSelector} and the folder field.
The parent must be a GridLayout with NUM_COL colums.
// separator
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
// label before type radios
label = new Label(parent, SWT.NONE);
label.setText("What type of resource would you like to create?");
label.setLayoutData(newGridData(NUM_COL));
// display the types on three columns of radio buttons.
emptyCell(parent);
Composite grid = new Composite(parent, SWT.NONE);
padWithEmptyCells(parent, 2);
grid.setLayout(new GridLayout(NUM_COL, true /*makeColumnsEqualWidth*/));
SelectionListener radioListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// single-click. Only do something if activated.
if (e.getSource() instanceof Button) {
onRadioTypeUpdated((Button) e.getSource());
}
}
};
int n = sTypes.length;
int num_lines = (n + NUM_COL/2) / NUM_COL;
for (int line = 0, k = 0; line < num_lines; line++) {
for (int i = 0; i < NUM_COL; i++, k++) {
if (k < n) {
TypeInfo type = sTypes[k];
Button radio = new Button(grid, SWT.RADIO);
type.setWidget(radio);
radio.setSelection(false);
radio.setText(type.getUiName());
radio.setToolTipText(type.getTooltip());
radio.addSelectionListener(radioListener);
} else {
emptyCell(grid);
}
}
}
// label before configuration selector
label = new Label(parent, SWT.NONE);
label.setText("What type of resource configuration would you like?");
label.setLayoutData(newGridData(NUM_COL));
// configuration selector
emptyCell(parent);
mConfigSelector = new ConfigurationSelector(parent);
GridData gd = newGridData(2, GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
gd.widthHint = ConfigurationSelector.WIDTH_HINT;
gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
mConfigSelector.setLayoutData(gd);
mConfigSelector.setOnChangeListener(new onConfigSelectorUpdated());
emptyCell(parent);
// folder name
String tooltip = "The folder where the file will be generated, relative to the project.";
label = new Label(parent, SWT.NONE);
label.setText("Folder");
label.setToolTipText(tooltip);
mWsFolderPathTextField = new Text(parent, SWT.BORDER);
mWsFolderPathTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mWsFolderPathTextField.setToolTipText(tooltip);
mWsFolderPathTextField.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
onWsFolderPathUpdated();
}
});
|
public void | dispose()
if (mSdkTargetChangeListener != null) {
AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
mSdkTargetChangeListener = null;
}
super.dispose();
|
private void | emptyCell(org.eclipse.swt.widgets.Composite parent)Helper method that creates an empty cell in the parent composite.
new Label(parent, SWT.NONE);
|
private void | enableTypesBasedOnApi()Helper method to enable the type radio buttons depending on the current API level.
A type radio button is enabled 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.
IAndroidTarget target = mProject != null ? Sdk.getCurrent().getTarget(mProject) : null;
int currentApiLevel = 1;
if (target != null) {
currentApiLevel = target.getApiVersionNumber();
}
for (TypeInfo type : sTypes) {
type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel);
}
|
public org.eclipse.core.resources.IFile | getDestinationFile()Returns an {@link IFile} on the destination file.
Uses {@link #getProject()}, {@link #getWsFolderPath()} and {@link #getFileName()}.
Returns null if the project, filename or folder are invalid and the destination file
cannot be determined.
The {@link IFile} is a resource. There might or might not be an actual real file.
IProject project = getProject();
String wsFolderPath = getWsFolderPath();
String fileName = getFileName();
if (project != null && wsFolderPath.length() > 0 && fileName.length() > 0) {
IPath dest = new Path(wsFolderPath).append(fileName);
IFile file = project.getFile(dest);
return file;
}
return null;
|
public java.lang.String | getFileName()Returns the destination filename or an empty string.
return mFileNameTextField == null ? "" : mFileNameTextField.getText(); //$NON-NLS-1$
|
public org.eclipse.core.resources.IProject | getProject()Returns the target project or null.
return mProject;
|
public java.lang.String | getRootElement()Returns the selected root element string, if any.
int index = mRootElementCombo.getSelectionIndex();
if (index >= 0) {
return mRootElementCombo.getItem(index);
}
return null;
|
public com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileCreationPage$TypeInfo | getSelectedType()Returns the {@link TypeInfo} for the currently selected type radio button.
Returns null if no radio button is selected.
TypeInfo type = null;
for (TypeInfo ti : sTypes) {
if (ti.getWidget().getSelection()) {
type = ti;
break;
}
}
return type;
|
public java.lang.String | getWsFolderPath()Returns the destination folder path relative to the project or an empty string.
return mWsFolderPathTextField == null ? "" : mWsFolderPathTextField.getText(); //$NON-NLS-1$
|
private void | initRootElementDescriptor(java.util.ArrayList roots, com.android.ide.eclipse.editors.descriptors.ElementDescriptor desc, java.util.HashSet visited)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.
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);
}
}
|
private void | initializeFromSelection(org.eclipse.jface.viewers.IStructuredSelection selection)Called by {@link NewXmlFileWizard} to initialize the page with the selection
received by the wizard -- typically the current user workbench selection.
Things we expect to find out from the selection:
- The project name, valid if it's an android nature.
- The current folder, valid if it's a folder under /res
- An existing filename, in which case the user will be asked whether to override it.
if (selection == null) {
return;
}
// 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(AndroidConstants.NATURE)) {
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;
if (res.getType() == IResource.FOLDER) {
wsFolderPath = res.getProjectRelativePath();
} else if (res.getType() == IResource.FILE) {
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;
}
}
}
// Now set the UI accordingly
if (targetScore > 0) {
mProject = targetProject;
mProjectTextField.setText(targetProject != null ? targetProject.getName() : ""); //$NON-NLS-1$
mFileNameTextField.setText(targetFileName != null ? targetFileName : ""); //$NON-NLS-1$
mWsFolderPathTextField.setText(targetWsFolderPath != null ? targetWsFolderPath : ""); //$NON-NLS-1$
}
|
private void | initializeRootValues()Initialize the root values of the type infos based on the current framework values.
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 && mProject != 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(mProject);
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$
mProject.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(), mProject.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);
}
}
|
private void | installTargetChangeListener()
mSdkTargetChangeListener = new ITargetChangeListener() {
public void onProjectTargetChange(IProject changedProject) {
// If this is the current project, force it to reload its data
if (changedProject != null && changedProject == mProject) {
changeProject(mProject);
}
}
public void onTargetsLoaded() {
// Reload the current project, if any, in case its target has changed.
if (mProject != null) {
changeProject(mProject);
}
}
};
AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
|
private org.eclipse.swt.layout.GridData | newGridData(int horizSpan)Helper method to create a new GridData with an horizontal span.
GridData gd = new GridData();
gd.horizontalSpan = horizSpan;
return gd;
|
private org.eclipse.swt.layout.GridData | newGridData(int horizSpan, int style)Helper method to create a new GridData with an horizontal span and a style.
GridData gd = new GridData(style);
gd.horizontalSpan = horizSpan;
return gd;
|
private void | onProjectBrowse()Callback called when the user uses the "Browse Projects" button.
IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectTextField.getText());
if (p != null) {
changeProject(p.getProject());
mProjectTextField.setText(mProject.getName());
}
|
private void | onProjectFieldUpdated()Callback called when the user edits the project text field.
String project = mProjectTextField.getText();
// Is this a valid project?
IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null /*javaModel*/);
IProject found = null;
for (IJavaProject p : projects) {
if (p.getProject().getName().equals(project)) {
found = p.getProject();
break;
}
}
if (found != mProject) {
changeProject(found);
}
|
private void | onRadioTypeUpdated(org.eclipse.swt.widgets.Button typeWidget)Callback called when one of the type radio button is changed.
// Do nothing if this is an internal modification or if the widget has been
// de-selected.
if (mInternalTypeUpdate || !typeWidget.getSelection()) {
return;
}
// Find type info that has just been enabled.
TypeInfo type = null;
for (TypeInfo ti : sTypes) {
if (ti.getWidget() == typeWidget) {
type = ti;
break;
}
}
if (type == null) {
return;
}
// update the combo
updateRootCombo(type);
// update the folder path
String wsFolderPath = mWsFolderPathTextField.getText();
String newPath = null;
mConfigSelector.getConfiguration(mTempConfig);
ResourceQualifier qual = mTempConfig.getInvalidQualifier();
if (qual == null) {
// The configuration is valid. Reformat the folder path using the canonical
// value from the configuration.
newPath = RES_FOLDER_ABS + mTempConfig.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.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 + mTempConfig.getFolderName(type.getResFolderType());
}
}
if (newPath != null && !newPath.equals(wsFolderPath)) {
mInternalWsFolderPathUpdate = true;
mWsFolderPathTextField.setText(newPath);
mInternalWsFolderPathUpdate = false;
}
validatePage();
|
private void | onWsFolderPathUpdated()Callback called when the Folder text field is changed, either programmatically
or by the user.
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$
ArrayList<TypeInfo> matches = new ArrayList<TypeInfo>();
// 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;
}
if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
wsFolderPath = wsFolderPath.substring(RES_FOLDER_ABS.length());
int pos = wsFolderPath.indexOf(AndroidConstants.WS_SEP_CHAR);
if (pos >= 0) {
wsFolderPath = wsFolderPath.substring(0, pos);
}
String[] folderSegments = wsFolderPath.split(FolderConfiguration.QUALIFIER_SEP);
if (folderSegments.length > 0) {
String folderName = folderSegments[0];
// update config selector
mInternalConfigSelectorUpdate = true;
mConfigSelector.setConfiguration(folderSegments);
mInternalConfigSelectorUpdate = false;
boolean selected = false;
for (TypeInfo type : sTypes) {
if (type.getResFolderName().equals(folderName)) {
matches.add(type);
selected |= type.getWidget().getSelection();
}
}
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);
}
}
}
validatePage();
|
private int | padWithEmptyCells(org.eclipse.swt.widgets.Composite parent, int col)Pads the parent with empty cells to match the number of columns of the parent grid.
for (; col < NUM_COL; ++col) {
emptyCell(parent);
}
col = 0;
return col;
|
private void | selectType(com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileCreationPage$TypeInfo type)Helper method to select on of the type radio buttons.
if (type == null || !type.getWidget().getSelection()) {
mInternalTypeUpdate = true;
mCurrentTypeInfo = type;
for (TypeInfo type2 : sTypes) {
type2.getWidget().setSelection(type2 == type);
}
updateRootCombo(type);
mInternalTypeUpdate = false;
}
|
public void | setInitialSelection(org.eclipse.jface.viewers.IStructuredSelection initialSelection)
mInitialSelection = initialSelection;
|
private void | updateRootCombo(com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileCreationPage$TypeInfo type)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.
// reset all the values in the combo
mRootElementCombo.removeAll();
if (type != null) {
// get the list of roots. The list can be empty but not null.
ArrayList<String> roots = type.getRoots();
// enable the combo if there's more than one choice
mRootElementCombo.setEnabled(roots != null && roots.size() > 1);
for (String root : roots) {
mRootElementCombo.add(root);
}
int index = 0; // default is to select the first one
String defaultRoot = type.getDefaultRoot();
if (defaultRoot != null) {
index = roots.indexOf(defaultRoot);
}
mRootElementCombo.select(index < 0 ? 0 : index);
}
|
private void | validatePage()Validates the fields, displays errors and warnings.
Enables the finish button if there are no errors.
String error = null;
String warning = null;
// -- validate project
if (getProject() == null) {
error = "Please select an Android project.";
}
// -- validate filename
if (error == null) {
String fileName = getFileName();
if (fileName == null || fileName.length() == 0) {
error = "A destination file name is required.";
} else if (!fileName.endsWith(AndroidConstants.DOT_XML)) {
error = String.format("The filename must end with %1$s.", AndroidConstants.DOT_XML);
}
}
// -- validate type
if (error == null) {
TypeInfo type = getSelectedType();
if (type == null) {
error = "One of the types must be selected (e.g. layout, values, etc.)";
}
}
// -- validate type API level
if (error == null) {
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
int currentApiLevel = 1;
if (target != null) {
currentApiLevel = target.getApiVersionNumber();
}
TypeInfo type = getSelectedType();
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 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 = 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, WizardPage.ERROR);
} else if (warning != null) {
setMessage(warning, WizardPage.WARNING);
} else {
setErrorMessage(null);
setMessage(null);
}
|