UiClassAttributeNodepublic class UiClassAttributeNode extends com.android.ide.eclipse.editors.uimodel.UiTextAttributeNode Represents an XML attribute for a class, that can be modified using a simple text field or
a dialog to choose an existing class. Also, there's a link to create a new class.
See {@link UiTextAttributeNode} for more information. |
Fields Summary |
---|
private String | mReferenceClass | private IPostTypeCreationAction | mPostCreationAction | private boolean | mMandatory | private final boolean | mDefaultToProjectOnly |
Methods Summary |
---|
private void | createNewClass(java.lang.String packageName, java.lang.String className)
// create the wizard page for the class creation, and configure it
NewClassWizardPage page = new NewClassWizardPage();
// set the parent class
page.setSuperClass(mReferenceClass, true /* canBeModified */);
// get the source folders as java elements.
IPackageFragmentRoot[] roots = getPackageFragmentRoots(getProject(),
true /*include_containers*/);
IPackageFragmentRoot currentRoot = null;
IPackageFragment currentFragment = null;
int packageMatchCount = -1;
for (IPackageFragmentRoot root : roots) {
// Get the java element for the package.
// This method is said to always return a IPackageFragment even if the
// underlying folder doesn't exist...
IPackageFragment fragment = root.getPackageFragment(packageName);
if (fragment != null && fragment.exists()) {
// we have a perfect match! we use it.
currentRoot = root;
currentFragment = fragment;
packageMatchCount = -1;
break;
} else {
// we don't have a match. we look for the fragment with the best match
// (ie the closest parent package we can find)
try {
IJavaElement[] children;
children = root.getChildren();
for (IJavaElement child : children) {
if (child instanceof IPackageFragment) {
fragment = (IPackageFragment)child;
if (packageName.startsWith(fragment.getElementName())) {
// its a match. get the number of segments
String[] segments = fragment.getElementName().split("\\."); //$NON-NLS-1$
if (segments.length > packageMatchCount) {
packageMatchCount = segments.length;
currentFragment = fragment;
currentRoot = root;
}
}
}
}
} catch (JavaModelException e) {
// Couldn't get the children: we just ignore this package root.
}
}
}
ArrayList<IPackageFragment> createdFragments = null;
if (currentRoot != null) {
// if we have a perfect match, we set it and we're done.
if (packageMatchCount == -1) {
page.setPackageFragmentRoot(currentRoot, true /* canBeModified*/);
page.setPackageFragment(currentFragment, true /* canBeModified */);
} else {
// we have a partial match.
// create the package. We have to start with the first segment so that we
// know what to delete in case of a cancel.
try {
createdFragments = new ArrayList<IPackageFragment>();
int totalCount = packageName.split("\\.").length; //$NON-NLS-1$
int count = 0;
int index = -1;
// skip the matching packages
while (count < packageMatchCount) {
index = packageName.indexOf('.", index+1);
count++;
}
// create the rest of the segments, except for the last one as indexOf will
// return -1;
while (count < totalCount - 1) {
index = packageName.indexOf('.", index+1);
count++;
createdFragments.add(currentRoot.createPackageFragment(
packageName.substring(0, index),
true /* force*/, new NullProgressMonitor()));
}
// create the last package
createdFragments.add(currentRoot.createPackageFragment(
packageName, true /* force*/, new NullProgressMonitor()));
// set the root and fragment in the Wizard page
page.setPackageFragmentRoot(currentRoot, true /* canBeModified*/);
page.setPackageFragment(createdFragments.get(createdFragments.size()-1),
true /* canBeModified */);
} catch (JavaModelException e) {
// if we can't create the packages, there's a problem. we revert to the default
// package
for (IPackageFragmentRoot root : roots) {
// Get the java element for the package.
// This method is said to always return a IPackageFragment even if the
// underlying folder doesn't exist...
IPackageFragment fragment = root.getPackageFragment(packageName);
if (fragment != null && fragment.exists()) {
page.setPackageFragmentRoot(root, true /* canBeModified*/);
page.setPackageFragment(fragment, true /* canBeModified */);
break;
}
}
}
}
} else if (roots.length > 0) {
// if we haven't found a valid fragment, we set the root to the first source folder.
page.setPackageFragmentRoot(roots[0], true /* canBeModified*/);
}
// if we have a starting class name we use it
if (className != null) {
page.setTypeName(className, true /* canBeModified*/);
}
// create the action that will open it the wizard.
OpenNewClassWizardAction action = new OpenNewClassWizardAction();
action.setConfiguredWizardPage(page);
action.run();
IJavaElement element = action.getCreatedElement();
if (element != null) {
if (element.getElementType() == IJavaElement.TYPE) {
IType type = (IType)element;
if (mPostCreationAction != null) {
mPostCreationAction.processNewType(type);
}
handleNewType(type);
}
} else {
// lets delete the packages we created just for this.
// we need to start with the leaf and go up
if (createdFragments != null) {
try {
for (int i = createdFragments.size() - 1 ; i >= 0 ; i--) {
createdFragments.get(i).delete(true /* force*/, new NullProgressMonitor());
}
} catch (JavaModelException e) {
e.printStackTrace();
}
}
}
| public void | createUiControl(org.eclipse.swt.widgets.Composite parent, org.eclipse.ui.forms.IManagedForm managedForm)
setManagedForm(managedForm);
FormToolkit toolkit = managedForm.getToolkit();
TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
StringBuilder label = new StringBuilder();
label.append("<form><p><a href='unused'>");
label.append(desc.getUiName());
label.append("</a></p></form>");
FormText formText = SectionHelper.createFormText(parent, toolkit, true /* isHtml */,
label.toString(), true /* setupLayoutData */);
formText.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
super.linkActivated(e);
handleLabelClick();
}
});
formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
SectionHelper.addControlTooltip(formText, desc.getTooltip());
Composite composite = toolkit.createComposite(parent);
composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
GridLayout gl = new GridLayout(2, false);
gl.marginHeight = gl.marginWidth = 0;
composite.setLayout(gl);
// Fixes missing text borders under GTK... also requires adding a 1-pixel margin
// for the text field below
toolkit.paintBordersFor(composite);
final Text text = toolkit.createText(composite, getCurrentValue());
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalIndent = 1; // Needed by the fixed composite borders under GTK
text.setLayoutData(gd);
Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
setTextWidget(text);
browseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
handleBrowseClick();
}
});
| private java.lang.String | getManifestPackage()Returns the current value of the /manifest/package attribute.
// get the root uiNode to get the 'package' attribute value.
UiElementNode rootNode = getUiParent().getUiRoot();
Element xmlElement = (Element) rootNode.getXmlNode();
if (xmlElement != null) {
return xmlElement.getAttribute(AndroidManifestDescriptors.PACKAGE_ATTR);
}
return ""; //$NON-NLS-1$
| private org.eclipse.jdt.core.IPackageFragmentRoot[] | getPackageFragmentRoots(org.eclipse.core.resources.IProject project, boolean include_containers)Computes and return the {@link IPackageFragmentRoot}s corresponding to the source folders of
the specified project.
ArrayList<IPackageFragmentRoot> result = new ArrayList<IPackageFragmentRoot>();
try {
IJavaProject javaProject = JavaCore.create(project);
IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
IClasspathEntry entry = roots[i].getRawClasspathEntry();
if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE ||
(include_containers &&
entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER)) {
result.add(roots[i]);
}
}
} catch (JavaModelException e) {
}
return result.toArray(new IPackageFragmentRoot[result.size()]);
| public java.lang.String[] | getPossibleValues(java.lang.String prefix)
// TODO: compute a list of existing classes for content assist completion
return null;
| private org.eclipse.core.resources.IProject | getProject()
UiElementNode uiNode = getUiParent();
AndroidEditor editor = uiNode.getEditor();
IEditorInput input = editor.getEditorInput();
if (input instanceof IFileEditorInput) {
// from the file editor we can get the IFile object, and from it, the IProject.
IFile file = ((IFileEditorInput)input).getFile();
return file.getProject();
}
return null;
| private void | handleBrowseClick()
Text text = getTextWidget();
// we need to get the project of the manifest.
IProject project = getProject();
if (project != null) {
// Create a search scope including only the source folder of the current
// project.
IPackageFragmentRoot[] packageFragmentRoots = getPackageFragmentRoots(project,
true /*include_containers*/);
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(
packageFragmentRoots,
false);
try {
SelectionDialog dlg = JavaUI.createTypeDialog(text.getShell(),
PlatformUI.getWorkbench().getProgressService(),
scope,
IJavaElementSearchConstants.CONSIDER_CLASSES, // style
false, // no multiple selection
"**", //$NON-NLS-1$ //filter
new HierarchyTypeSelection(project, mReferenceClass));
dlg.setMessage(String.format("Select class name for element %1$s:",
getUiParent().getBreadcrumbTrailDescription(false /* include_root */)));
if (dlg instanceof ITypeSelectionComponent) {
((ITypeSelectionComponent)dlg).triggerSearch();
}
if (dlg.open() == Window.OK) {
Object[] results = dlg.getResult();
if (results.length == 1) {
handleNewType((IType)results[0]);
}
}
} catch (JavaModelException e1) {
AdtPlugin.log(e1, "UiClassAttributeNode HandleBrowser failed");
}
}
| private void | handleLabelClick()
// get the current value
String className = getTextWidget().getText().trim();
// get the package name from the manifest.
String packageName = getManifestPackage();
if (className.length() == 0) {
createNewClass(packageName, null /* className */);
} else {
// build back the fully qualified class name.
String fullClassName = className;
if (className.startsWith(".")) { //$NON-NLS-1$
fullClassName = packageName + className;
} else {
String[] segments = className.split(AndroidConstants.RE_DOT);
if (segments.length == 1) {
fullClassName = packageName + "." + className; //$NON-NLS-1$
}
}
// in case the type is enclosed, we need to replace the $ with .
fullClassName = fullClassName.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS2$
// now we try to find the file that contains this class and we open it in the editor.
IProject project = getProject();
IJavaProject javaProject = JavaCore.create(project);
try {
IType result = javaProject.findType(fullClassName);
if (result != null) {
JavaUI.openInEditor(result);
} else {
// split the last segment from the fullClassname
int index = fullClassName.lastIndexOf('.");
if (index != -1) {
createNewClass(fullClassName.substring(0, index),
fullClassName.substring(index+1));
} else {
createNewClass(packageName, className);
}
}
} catch (JavaModelException e) {
AdtPlugin.log(e, "UiClassAttributeNode HandleLabel failed");
} catch (PartInitException e) {
AdtPlugin.log(e, "UiClassAttributeNode HandleLabel failed");
}
}
| private void | handleNewType(org.eclipse.jdt.core.IType type)
Text text = getTextWidget();
// get the fully qualified name with $ to properly detect the enclosing types.
String name = type.getFullyQualifiedName('$");
String packageValue = getManifestPackage();
// check if the class doesn't start with the package.
if (packageValue.length() > 0 && name.startsWith(packageValue)) {
// if it does, we remove the package and the first dot.
name = name.substring(packageValue.length() + 1);
// look for how many segments we have left.
// if one, just write it that way.
// if more than one, write it with a leading dot.
String[] packages = name.split(AndroidConstants.RE_DOT);
if (packages.length == 1) {
text.setText(name);
} else {
text.setText("." + name); //$NON-NLS-1$
}
} else {
text.setText(name);
}
| protected void | onAddValidators(org.eclipse.swt.widgets.Text text)
ModifyListener listener = new ModifyListener() {
public void modifyText(ModifyEvent e) {
try {
String textValue = text.getText().trim();
if (textValue.length() == 0) {
if (mMandatory) {
setErrorMessage("Value is mandatory", text);
} else {
setErrorMessage(null, text);
}
return;
}
// first we need the current java package.
String javaPackage = getManifestPackage();
// build the fully qualified name of the class
String className = AndroidManifestParser.combinePackageAndClassName(
javaPackage, textValue);
// only test the vilibility for activities.
boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(
mReferenceClass);
// test the class
setErrorMessage(BaseProjectHelper.testClassForManifest(
BaseProjectHelper.getJavaProject(getProject()), className,
mReferenceClass, testVisibility), text);
} catch (CoreException ce) {
setErrorMessage(ce.getMessage(), text);
}
}
};
text.addModifyListener(listener);
// Make sure the validator removes its message(s) when the widget is disposed
text.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
// we don't want to use setErrorMessage, because we don't want to reset
// the error flag in the UiAttributeNode
getManagedForm().getMessageManager().removeMessage(text, text);
}
});
// Finally call the validator once to make sure the initial value is processed
listener.modifyText(null);
| private final void | setErrorMessage(java.lang.String message, org.eclipse.swt.widgets.Text textWidget)Sets the error messages. If message is null , the message is removed.
if (message != null) {
setHasError(true);
getManagedForm().getMessageManager().addMessage(textWidget, message, null /* data */,
IMessageProvider.ERROR, textWidget);
} else {
setHasError(false);
getManagedForm().getMessageManager().removeMessage(textWidget, textWidget);
}
|
|