diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest')
26 files changed, 0 insertions, 5816 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java deleted file mode 100644 index 1492adbb7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.editors.manifest; - -import static com.android.xml.AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION; -import static com.android.xml.AndroidManifest.ATTRIBUTE_TARGET_SDK_VERSION; - -import com.android.annotations.VisibleForTesting; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.utils.Pair; - -import org.eclipse.jface.text.contentassist.ICompletionProposal; -import org.w3c.dom.Node; - -import java.util.ArrayList; -import java.util.List; - -/** - * Content Assist Processor for AndroidManifest.xml - */ -@VisibleForTesting -public final class ManifestContentAssist extends AndroidContentAssist { - - /** - * Constructor for ManifestContentAssist - */ - public ManifestContentAssist() { - super(AndroidTargetData.DESCRIPTOR_MANIFEST); - } - - @Override - protected boolean computeAttributeValues(List<ICompletionProposal> proposals, int offset, - String parentTagName, String attributeName, Node node, String wordPrefix, - boolean skipEndTag, int replaceLength) { - if (attributeName.endsWith(ATTRIBUTE_MIN_SDK_VERSION) - || attributeName.endsWith(ATTRIBUTE_TARGET_SDK_VERSION)) { - // The user is completing the minSdkVersion attribute: it should be - // an integer for the API version, but we'll add full Android version - // names to make it more obvious what they're selecting - - List<Pair<String, String>> choices = new ArrayList<Pair<String, String>>(); - int max = AdtUtils.getHighestKnownApiLevel(); - // Look for any more recent installed versions the user may have - Sdk sdk = Sdk.getCurrent(); - if (sdk == null) { - return false; - } - IAndroidTarget[] targets = sdk.getTargets(); - for (IAndroidTarget target : targets) { - AndroidVersion version = target.getVersion(); - int apiLevel = version.getApiLevel(); - if (apiLevel > max) { - if (version.isPreview()) { - // Use codename, not API level, as version string for preview versions - choices.add(Pair.of(version.getCodename(), version.getCodename())); - } else { - choices.add(Pair.of(Integer.toString(apiLevel), target.getFullName())); - } - } - } - for (int api = max; api >= 1; api--) { - String name = AdtUtils.getAndroidName(api); - choices.add(Pair.of(Integer.toString(api), name)); - } - char needTag = 0; - addMatchingProposals(proposals, choices.toArray(), offset, node, wordPrefix, - needTag, true /* isAttribute */, false /* isNew */, - skipEndTag /* skipEndTag */, replaceLength); - return true; - } else { - return super.computeAttributeValues(proposals, offset, parentTagName, attributeName, - node, wordPrefix, skipEndTag, replaceLength); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java deleted file mode 100644 index 55ebf5970..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * 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.editors.manifest; - -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.ATTR_NAME; -import static com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors.USES_PERMISSION; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.ApplicationPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.InstrumentationPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.OverviewPage; -import com.android.ide.eclipse.adt.internal.editors.manifest.pages.PermissionPage; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; -import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import java.util.Collection; -import java.util.List; - -/** - * Multi-page form editor for AndroidManifest.xml. - */ -@SuppressWarnings("restriction") -public final class ManifestEditor extends AndroidXmlEditor { - - public static final String ID = AdtConstants.EDITORS_NAMESPACE + ".manifest.ManifestEditor"; //$NON-NLS-1$ - - private final static String EMPTY = ""; //$NON-NLS-1$ - - /** Root node of the UI element hierarchy */ - private UiElementNode mUiManifestNode; - /** The Application Page tab */ - private ApplicationPage mAppPage; - /** The Overview Manifest Page tab */ - private OverviewPage mOverviewPage; - /** The Permission Page tab */ - private PermissionPage mPermissionPage; - /** The Instrumentation Page tab */ - private InstrumentationPage mInstrumentationPage; - - private IFileListener mMarkerMonitor; - - - /** - * Creates the form editor for AndroidManifest.xml. - */ - public ManifestEditor() { - super(); - addDefaultTargetListener(); - } - - @Override - public void dispose() { - super.dispose(); - - GlobalProjectMonitor.getMonitor().removeFileListener(mMarkerMonitor); - } - - @Override - public void activated() { - super.activated(); - clearActionBindings(false); - } - - @Override - public void deactivated() { - super.deactivated(); - updateActionBindings(); - } - - @Override - protected void pageChange(int newPageIndex) { - super.pageChange(newPageIndex); - if (newPageIndex == mTextPageIndex) { - updateActionBindings(); - } else { - clearActionBindings(false); - } - } - - @Override - protected int getPersistenceCategory() { - return CATEGORY_MANIFEST; - } - - /** - * Return the root node of the UI element hierarchy, which here - * is the "manifest" node. - */ - @Override - public UiElementNode getUiRootNode() { - return mUiManifestNode; - } - - /** - * Returns the Manifest descriptors for the file being edited. - */ - public AndroidManifestDescriptors getManifestDescriptors() { - AndroidTargetData data = getTargetData(); - if (data != null) { - return data.getManifestDescriptors(); - } - - return null; - } - - // ---- Base Class Overrides ---- - - /** - * Returns whether the "save as" operation is supported by this editor. - * <p/> - * Save-As is a valid operation for the ManifestEditor since it acts on a - * single source file. - * - * @see IEditorPart - */ - @Override - public boolean isSaveAsAllowed() { - return true; - } - - @Override - public void doSave(IProgressMonitor monitor) { - // Look up the current (pre-save) values of minSdkVersion and targetSdkVersion - int prevMinSdkVersion = -1; - int prevTargetSdkVersion = -1; - IProject project = null; - ManifestInfo info = null; - try { - project = getProject(); - if (project != null) { - info = ManifestInfo.get(project); - prevMinSdkVersion = info.getMinSdkVersion(); - prevTargetSdkVersion = info.getTargetSdkVersion(); - info.clear(); - } - } catch (Throwable t) { - // We don't expect exceptions from the above calls, but we *really* - // need to make sure that nothing can prevent the save function from - // getting called! - AdtPlugin.log(t, null); - } - - // Actually save - super.doSave(monitor); - - // If the target/minSdkVersion has changed, clear all lint warnings (since many - // of them are tied to the min/target sdk levels), in order to avoid showing stale - // results - try { - if (info != null) { - int newMinSdkVersion = info.getMinSdkVersion(); - int newTargetSdkVersion = info.getTargetSdkVersion(); - if (newMinSdkVersion != prevMinSdkVersion - || newTargetSdkVersion != prevTargetSdkVersion) { - assert project != null; - EclipseLintClient.clearMarkers(project); - } - } - } catch (Throwable t) { - AdtPlugin.log(t, null); - } - } - - /** - * Creates the various form pages. - */ - @Override - protected void createFormPages() { - try { - addPage(mOverviewPage = new OverviewPage(this)); - addPage(mAppPage = new ApplicationPage(this)); - addPage(mPermissionPage = new PermissionPage(this)); - addPage(mInstrumentationPage = new InstrumentationPage(this)); - } catch (PartInitException e) { - AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$ - } - } - - /* (non-java doc) - * Change the tab/title name to include the project name. - */ - @Override - protected void setInput(IEditorInput input) { - super.setInput(input); - IFile inputFile = getInputFile(); - if (inputFile != null) { - startMonitoringMarkers(); - setPartName(String.format("%1$s Manifest", inputFile.getProject().getName())); - } - } - - /** - * Processes the new XML Model, which XML root node is given. - * - * @param xml_doc The XML document, if available, or null if none exists. - */ - @Override - protected void xmlModelChanged(Document xml_doc) { - // create the ui root node on demand. - initUiRootNode(false /*force*/); - - loadFromXml(xml_doc); - } - - private void loadFromXml(Document xmlDoc) { - mUiManifestNode.setXmlDocument(xmlDoc); - Node node = getManifestXmlNode(xmlDoc); - - if (node != null) { - // Refresh the manifest UI node and all its descendants - mUiManifestNode.loadFromXmlNode(node); - } - } - - private Node getManifestXmlNode(Document xmlDoc) { - if (xmlDoc != null) { - ElementDescriptor manifestDesc = mUiManifestNode.getDescriptor(); - String manifestXmlName = manifestDesc == null ? null : manifestDesc.getXmlName(); - assert manifestXmlName != null; - - if (manifestXmlName != null) { - Node node = xmlDoc.getDocumentElement(); - if (node != null && manifestXmlName.equals(node.getNodeName())) { - return node; - } - - for (node = xmlDoc.getFirstChild(); - node != null; - node = node.getNextSibling()) { - if (node.getNodeType() == Node.ELEMENT_NODE && - manifestXmlName.equals(node.getNodeName())) { - return node; - } - } - } - } - - return null; - } - - private void onDescriptorsChanged() { - IStructuredModel model = getModelForRead(); - if (model != null) { - try { - Node node = getManifestXmlNode(getXmlDocument(model)); - mUiManifestNode.reloadFromXmlNode(node); - } finally { - model.releaseFromRead(); - } - } - - if (mOverviewPage != null) { - mOverviewPage.refreshUiApplicationNode(); - } - - if (mAppPage != null) { - mAppPage.refreshUiApplicationNode(); - } - - if (mPermissionPage != null) { - mPermissionPage.refreshUiNode(); - } - - if (mInstrumentationPage != null) { - mInstrumentationPage.refreshUiNode(); - } - } - - /** - * Reads and processes the current markers and adds a listener for marker changes. - */ - private void startMonitoringMarkers() { - final IFile inputFile = getInputFile(); - if (inputFile != null) { - updateFromExistingMarkers(inputFile); - - mMarkerMonitor = new IFileListener() { - @Override - public void fileChanged(@NonNull IFile file, @NonNull IMarkerDelta[] markerDeltas, - int kind, @Nullable String extension, int flags, boolean isAndroidProject) { - if (isAndroidProject && file.equals(inputFile)) { - processMarkerChanges(markerDeltas); - } - } - }; - - GlobalProjectMonitor.getMonitor().addFileListener( - mMarkerMonitor, IResourceDelta.CHANGED); - } - } - - /** - * Processes the markers of the specified {@link IFile} and updates the error status of - * {@link UiElementNode}s and {@link UiAttributeNode}s. - * @param inputFile the file being edited. - */ - private void updateFromExistingMarkers(IFile inputFile) { - try { - // get the markers for the file - IMarker[] markers = inputFile.findMarkers( - AdtConstants.MARKER_ANDROID, true, IResource.DEPTH_ZERO); - - AndroidManifestDescriptors desc = getManifestDescriptors(); - if (desc != null) { - ElementDescriptor appElement = desc.getApplicationElement(); - - if (appElement != null && mUiManifestNode != null) { - UiElementNode appUiNode = mUiManifestNode.findUiChildNode( - appElement.getXmlName()); - List<UiElementNode> children = appUiNode.getUiChildren(); - - for (IMarker marker : markers) { - processMarker(marker, children, IResourceDelta.ADDED); - } - } - } - - } catch (CoreException e) { - // findMarkers can throw an exception, in which case, we'll do nothing. - } - } - - /** - * Processes a {@link IMarker} change. - * @param markerDeltas the list of {@link IMarkerDelta} - */ - private void processMarkerChanges(IMarkerDelta[] markerDeltas) { - AndroidManifestDescriptors descriptors = getManifestDescriptors(); - if (descriptors != null && descriptors.getApplicationElement() != null) { - UiElementNode app_ui_node = mUiManifestNode.findUiChildNode( - descriptors.getApplicationElement().getXmlName()); - List<UiElementNode> children = app_ui_node.getUiChildren(); - - for (IMarkerDelta markerDelta : markerDeltas) { - processMarker(markerDelta.getMarker(), children, markerDelta.getKind()); - } - } - } - - /** - * Processes a new/old/updated marker. - * @param marker The marker being added/removed/changed - * @param nodeList the list of activity/service/provider/receiver nodes. - * @param kind the change kind. Can be {@link IResourceDelta#ADDED}, - * {@link IResourceDelta#REMOVED}, or {@link IResourceDelta#CHANGED} - */ - private void processMarker(IMarker marker, List<UiElementNode> nodeList, int kind) { - // get the data from the marker - String nodeType = marker.getAttribute(AdtConstants.MARKER_ATTR_TYPE, EMPTY); - if (nodeType == EMPTY) { - return; - } - - String className = marker.getAttribute(AdtConstants.MARKER_ATTR_CLASS, EMPTY); - if (className == EMPTY) { - return; - } - - for (UiElementNode ui_node : nodeList) { - if (ui_node.getDescriptor().getXmlName().equals(nodeType)) { - for (UiAttributeNode attr : ui_node.getAllUiAttributes()) { - if (attr.getDescriptor().getXmlLocalName().equals( - AndroidManifestDescriptors.ANDROID_NAME_ATTR)) { - if (attr.getCurrentValue().equals(className)) { - if (kind == IResourceDelta.REMOVED) { - attr.setHasError(false); - } else { - attr.setHasError(true); - } - return; - } - } - } - } - } - } - - /** - * Creates the initial UI Root Node, including the known mandatory elements. - * @param force if true, a new UiManifestNode is recreated even if it already exists. - */ - @Override - protected void initUiRootNode(boolean force) { - // The manifest UI node is always created, even if there's no corresponding XML node. - if (mUiManifestNode != null && force == false) { - return; - } - - AndroidManifestDescriptors manifestDescriptor = getManifestDescriptors(); - - if (manifestDescriptor != null) { - ElementDescriptor manifestElement = manifestDescriptor.getManifestElement(); - mUiManifestNode = manifestElement.createUiNode(); - mUiManifestNode.setEditor(this); - - // Similarly, always create the /manifest/uses-sdk followed by /manifest/application - // (order of the elements now matters) - ElementDescriptor element = manifestDescriptor.getUsesSdkElement(); - boolean present = false; - for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) { - if (ui_node.getDescriptor() == element) { - present = true; - break; - } - } - if (!present) { - mUiManifestNode.appendNewUiChild(element); - } - - element = manifestDescriptor.getApplicationElement(); - present = false; - for (UiElementNode ui_node : mUiManifestNode.getUiChildren()) { - if (ui_node.getDescriptor() == element) { - present = true; - break; - } - } - if (!present) { - mUiManifestNode.appendNewUiChild(element); - } - - onDescriptorsChanged(); - } else { - // create a dummy descriptor/uinode until we have real descriptors - ElementDescriptor desc = new ElementDescriptor("manifest", //$NON-NLS-1$ - "temporary descriptors due to missing decriptors", //$NON-NLS-1$ - null /*tooltip*/, null /*sdk_url*/, null /*attributes*/, - null /*children*/, false /*mandatory*/); - mUiManifestNode = desc.createUiNode(); - mUiManifestNode.setEditor(this); - } - } - - /** - * Adds the given set of permissions into the manifest file in the suitable - * location - * - * @param permissions permission fqcn's to be added - * @param show if true, show one or more of the newly added permissions - */ - public void addPermissions(@NonNull final List<String> permissions, final boolean show) { - wrapUndoEditXmlModel("Add permissions", new Runnable() { - @Override - public void run() { - // Ensure that the model is current: - initUiRootNode(true /*force*/); - UiElementNode root = getUiRootNode(); - - ElementDescriptor descriptor = getManifestDescriptors().getUsesPermissionElement(); - boolean shown = false; - for (String permission : permissions) { - // Find the first permission which sorts alphabetically laster than - // this permission (or the last permission, if none are after in the alphabet) - // and insert it there - int lastPermissionIndex = -1; - int nextPermissionIndex = -1; - int index = 0; - for (UiElementNode sibling : root.getUiChildren()) { - Node node = sibling.getXmlNode(); - if (node.getNodeName().equals(USES_PERMISSION)) { - lastPermissionIndex = index; - String name = ((Element) node).getAttributeNS(ANDROID_URI, ATTR_NAME); - if (permission.compareTo(name) < 0) { - nextPermissionIndex = index; - break; - } - } else if (node.getNodeName().equals("application")) { //$NON-NLS-1$ - // permissions should come before the application element - nextPermissionIndex = index; - break; - } - index++; - } - - if (nextPermissionIndex != -1) { - index = nextPermissionIndex; - } else if (lastPermissionIndex != -1) { - index = lastPermissionIndex + 1; - } else { - index = root.getUiChildren().size(); - } - UiElementNode usesPermission = root.insertNewUiChild(index, descriptor); - usesPermission.setAttributeValue(ATTR_NAME, ANDROID_URI, permission, - true /*override*/); - Node node = usesPermission.createXmlNode(); - if (show && !shown) { - shown = true; - if (node instanceof IndexedRegion && getInputFile() != null) { - IndexedRegion indexedRegion = (IndexedRegion) node; - IRegion region = new Region(indexedRegion.getStartOffset(), - indexedRegion.getEndOffset() - indexedRegion.getStartOffset()); - try { - AdtPlugin.openFile(getInputFile(), region, true /*show*/); - } catch (PartInitException e) { - AdtPlugin.log(e, null); - } - } else { - show(node); - } - } - } - } - }); - } - - /** - * Removes the permissions from the manifest editor - * - * @param permissions the permission fqcn's to be removed - */ - public void removePermissions(@NonNull final Collection<String> permissions) { - wrapUndoEditXmlModel("Remove permissions", new Runnable() { - @Override - public void run() { - // Ensure that the model is current: - initUiRootNode(true /*force*/); - UiElementNode root = getUiRootNode(); - - for (String permission : permissions) { - for (UiElementNode sibling : root.getUiChildren()) { - Node node = sibling.getXmlNode(); - if (node.getNodeName().equals(USES_PERMISSION)) { - String name = ((Element) node).getAttributeNS(ANDROID_URI, ATTR_NAME); - if (name.equals(permission)) { - sibling.deleteXmlNode(); - break; - } - } - } - } - } - }); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java deleted file mode 100644 index 8beca30b8..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.editors.manifest; - -import org.eclipse.jface.action.IAction; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.ide.IDEActionFactory; -import org.eclipse.ui.part.MultiPageEditorActionBarContributor; -import org.eclipse.ui.texteditor.ITextEditor; -import org.eclipse.ui.texteditor.ITextEditorActionConstants; - -/** - * Manages the installation/deinstallation of global actions for multi-page - * editors. Responsible for the redirection of global actions to the active - * editor. Multi-page contributor replaces the contributors for the individual - * editors in the multi-page editor. - * - * TODO: Doesn't look like we need this. Remove it if not needed. - * @deprecated - */ -final class ManifestEditorContributor extends MultiPageEditorActionBarContributor { - private IEditorPart mActiveEditorPart; - - /** - * Creates a multi-page contributor. - * - * Marked as Private so it can't be instanciated. This is a cheap way to make sure - * it's not being used. As noted in constructor, should be removed if not used. - * @deprecated - */ - private ManifestEditorContributor() { - super(); - } - - /** - * Returns the action registed with the given text editor. - * - * @return IAction or null if editor is null. - */ - protected IAction getAction(ITextEditor editor, String actionID) { - return (editor == null ? null : editor.getAction(actionID)); - } - - /* - * (non-JavaDoc) Method declared in - * AbstractMultiPageEditorActionBarContributor. - */ - - @Override - public void setActivePage(IEditorPart part) { - if (mActiveEditorPart == part) - return; - - mActiveEditorPart = part; - - IActionBars actionBars = getActionBars(); - if (actionBars != null) { - - ITextEditor editor = - (part instanceof ITextEditor) ? (ITextEditor)part : null; - - actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), - getAction(editor, ITextEditorActionConstants.DELETE)); - actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), - getAction(editor, ITextEditorActionConstants.UNDO)); - actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), - getAction(editor, ITextEditorActionConstants.REDO)); - actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), - getAction(editor, ITextEditorActionConstants.CUT)); - actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), - getAction(editor, ITextEditorActionConstants.COPY)); - actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), - getAction(editor, ITextEditorActionConstants.PASTE)); - actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), - getAction(editor, ITextEditorActionConstants.SELECT_ALL)); - actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), - getAction(editor, ITextEditorActionConstants.FIND)); - actionBars.setGlobalActionHandler( - IDEActionFactory.BOOKMARK.getId(), getAction(editor, - IDEActionFactory.BOOKMARK.getId())); - actionBars.updateActionBars(); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java deleted file mode 100644 index 6d2d1c1f2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestInfo.java +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Copyright (C) 2011 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.editors.manifest; - -import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX; -import static com.android.SdkConstants.CLASS_ACTIVITY; -import static com.android.SdkConstants.NS_RESOURCES; -import static com.android.xml.AndroidManifest.ATTRIBUTE_ICON; -import static com.android.xml.AndroidManifest.ATTRIBUTE_LABEL; -import static com.android.xml.AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION; -import static com.android.xml.AndroidManifest.ATTRIBUTE_NAME; -import static com.android.xml.AndroidManifest.ATTRIBUTE_PACKAGE; -import static com.android.xml.AndroidManifest.ATTRIBUTE_PARENT_ACTIVITY_NAME; -import static com.android.xml.AndroidManifest.ATTRIBUTE_SUPPORTS_RTL; -import static com.android.xml.AndroidManifest.ATTRIBUTE_TARGET_SDK_VERSION; -import static com.android.xml.AndroidManifest.ATTRIBUTE_THEME; -import static com.android.xml.AndroidManifest.ATTRIBUTE_UI_OPTIONS; -import static com.android.xml.AndroidManifest.ATTRIBUTE_VALUE; -import static com.android.xml.AndroidManifest.NODE_ACTIVITY; -import static com.android.xml.AndroidManifest.NODE_METADATA; -import static com.android.xml.AndroidManifest.NODE_USES_SDK; -import static com.android.xml.AndroidManifest.VALUE_PARENT_ACTIVITY; -import static org.eclipse.jdt.core.search.IJavaSearchConstants.REFERENCES; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.ide.eclipse.adt.io.IFolderWrapper; -import com.android.io.IAbstractFile; -import com.android.io.StreamException; -import com.android.resources.ScreenSize; -import com.android.sdklib.IAndroidTarget; -import com.android.utils.Pair; -import com.android.xml.AndroidManifest; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.jdt.core.IField; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeHierarchy; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; -import org.eclipse.jdt.core.search.SearchMatch; -import org.eclipse.jdt.core.search.SearchParticipant; -import org.eclipse.jdt.core.search.SearchPattern; -import org.eclipse.jdt.core.search.SearchRequestor; -import org.eclipse.jdt.internal.core.BinaryType; -import org.eclipse.jface.text.IDocument; -import org.eclipse.ui.editors.text.TextFileDocumentProvider; -import org.eclipse.ui.texteditor.IDocumentProvider; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPathExpressionException; - -/** - * Retrieves and caches manifest information such as the themes to be used for - * a given activity. - * - * @see AndroidManifest - */ -public class ManifestInfo { - - public static class ActivityAttributes { - @Nullable - private final String mIcon; - @Nullable - private final String mLabel; - @NonNull - private final String mName; - @Nullable - private final String mParentActivity; - @Nullable - private final String mTheme; - @Nullable - private final String mUiOptions; - - public ActivityAttributes(Element activity, String packageName) { - - // Get activity name. - String name = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_NAME); - if (name == null || name.length() == 0) { - throw new RuntimeException("Activity name cannot be empty"); - } - int index = name.indexOf('.'); - if (index <= 0 && packageName != null && !packageName.isEmpty()) { - name = packageName + (index == -1 ? "." : "") + name; - } - mName = name; - - // Get activity icon. - String value = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON); - if (value != null && value.length() > 0) { - mIcon = value; - } else { - mIcon = null; - } - - // Get activity label. - value = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL); - if (value != null && value.length() > 0) { - mLabel = value; - } else { - mLabel = null; - } - - // Get activity parent. Also search the meta-data for parent info. - value = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_PARENT_ACTIVITY_NAME); - if (value == null || value.length() == 0) { - // TODO: Not sure if meta data can be used for API Level > 16 - NodeList metaData = activity.getElementsByTagName(NODE_METADATA); - for (int j = 0, m = metaData.getLength(); j < m; j++) { - Element data = (Element) metaData.item(j); - String metadataName = data.getAttributeNS(NS_RESOURCES, ATTRIBUTE_NAME); - if (VALUE_PARENT_ACTIVITY.equals(metadataName)) { - value = data.getAttributeNS(NS_RESOURCES, ATTRIBUTE_VALUE); - if (value != null) { - index = value.indexOf('.'); - if (index <= 0 && packageName != null && !packageName.isEmpty()) { - value = packageName + (index == -1 ? "." : "") + value; - break; - } - } - } - } - } - if (value != null && value.length() > 0) { - mParentActivity = value; - } else { - mParentActivity = null; - } - - // Get activity theme. - value = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_THEME); - if (value != null && value.length() > 0) { - mTheme = value; - } else { - mTheme = null; - } - - // Get UI options. - value = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_UI_OPTIONS); - if (value != null && value.length() > 0) { - mUiOptions = value; - } else { - mUiOptions = null; - } - } - - @Nullable - public String getIcon() { - return mIcon; - } - - @Nullable - public String getLabel() { - return mLabel; - } - - public String getName() { - return mName; - } - - @Nullable - public String getParentActivity() { - return mParentActivity; - } - - @Nullable - public String getTheme() { - return mTheme; - } - - @Nullable - public String getUiOptions() { - return mUiOptions; - } - } - - /** - * The maximum number of milliseconds to search for an activity in the codebase when - * attempting to associate layouts with activities in - * {@link #guessActivity(IFile, String)} - */ - private static final int SEARCH_TIMEOUT_MS = 3000; - - private final IProject mProject; - private String mPackage; - private String mManifestTheme; - private Map<String, ActivityAttributes> mActivityAttributes; - private IAbstractFile mManifestFile; - private long mLastModified; - private long mLastChecked; - private String mMinSdkName; - private int mMinSdk; - private int mTargetSdk; - private String mApplicationIcon; - private String mApplicationLabel; - private boolean mApplicationSupportsRtl; - - /** - * Qualified name for the per-project non-persistent property storing the - * {@link ManifestInfo} for this project - */ - final static QualifiedName MANIFEST_FINDER = new QualifiedName(AdtPlugin.PLUGIN_ID, - "manifest"); //$NON-NLS-1$ - - /** - * Constructs an {@link ManifestInfo} for the given project. Don't use this method; - * use the {@link #get} factory method instead. - * - * @param project project to create an {@link ManifestInfo} for - */ - private ManifestInfo(IProject project) { - mProject = project; - } - - /** - * Clears the cached manifest information. The next get call on one of the - * properties will cause the information to be refreshed. - */ - public void clear() { - mLastChecked = 0; - } - - /** - * Returns the {@link ManifestInfo} for the given project - * - * @param project the project the finder is associated with - * @return a {@ManifestInfo} for the given project, never null - */ - @NonNull - public static ManifestInfo get(IProject project) { - ManifestInfo finder = null; - try { - finder = (ManifestInfo) project.getSessionProperty(MANIFEST_FINDER); - } catch (CoreException e) { - // Not a problem; we will just create a new one - } - - if (finder == null) { - finder = new ManifestInfo(project); - try { - project.setSessionProperty(MANIFEST_FINDER, finder); - } catch (CoreException e) { - AdtPlugin.log(e, "Can't store ManifestInfo"); - } - } - - return finder; - } - - /** - * Ensure that the package, theme and activity maps are initialized and up to date - * with respect to the manifest file - */ - private void sync() { - // Since each of the accessors call sync(), allow a bunch of immediate - // accessors to all bypass the file stat() below - long now = System.currentTimeMillis(); - if (now - mLastChecked < 50 && mManifestFile != null) { - return; - } - mLastChecked = now; - - if (mManifestFile == null) { - IFolderWrapper projectFolder = new IFolderWrapper(mProject); - mManifestFile = AndroidManifest.getManifest(projectFolder); - if (mManifestFile == null) { - return; - } - } - - // Check to see if our data is up to date - long fileModified = mManifestFile.getModificationStamp(); - if (fileModified == mLastModified) { - // Already have up to date data - return; - } - mLastModified = fileModified; - - mActivityAttributes = new HashMap<String, ActivityAttributes>(); - mManifestTheme = null; - mTargetSdk = 1; // Default when not specified - mMinSdk = 1; // Default when not specified - mMinSdkName = "1"; // Default when not specified - mPackage = ""; //$NON-NLS-1$ - mApplicationIcon = null; - mApplicationLabel = null; - mApplicationSupportsRtl = false; - - Document document = null; - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - InputSource is = new InputSource(mManifestFile.getContents()); - - factory.setNamespaceAware(true); - factory.setValidating(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - document = builder.parse(is); - - Element root = document.getDocumentElement(); - mPackage = root.getAttribute(ATTRIBUTE_PACKAGE); - NodeList activities = document.getElementsByTagName(NODE_ACTIVITY); - for (int i = 0, n = activities.getLength(); i < n; i++) { - Element activity = (Element) activities.item(i); - ActivityAttributes info = new ActivityAttributes(activity, mPackage); - mActivityAttributes.put(info.getName(), info); - } - - NodeList applications = root.getElementsByTagName(AndroidManifest.NODE_APPLICATION); - if (applications.getLength() > 0) { - assert applications.getLength() == 1; - Element application = (Element) applications.item(0); - if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON)) { - mApplicationIcon = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON); - } - if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL)) { - mApplicationLabel = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL); - } - if (SdkConstants.VALUE_TRUE.equals(application.getAttributeNS(NS_RESOURCES, - ATTRIBUTE_SUPPORTS_RTL))) { - mApplicationSupportsRtl = true; - } - - String defaultTheme = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_THEME); - if (defaultTheme != null && !defaultTheme.isEmpty()) { - // From manifest theme documentation: - // "If that attribute is also not set, the default system theme is used." - mManifestTheme = defaultTheme; - } - } - - // Look up target SDK - NodeList usesSdks = root.getElementsByTagName(NODE_USES_SDK); - if (usesSdks.getLength() > 0) { - Element usesSdk = (Element) usesSdks.item(0); - mMinSdk = getApiVersion(usesSdk, ATTRIBUTE_MIN_SDK_VERSION, 1); - mTargetSdk = getApiVersion(usesSdk, ATTRIBUTE_TARGET_SDK_VERSION, mMinSdk); - } - - } catch (SAXException e) { - AdtPlugin.log(e, "Malformed manifest"); - } catch (Exception e) { - AdtPlugin.log(e, "Could not read Manifest data"); - } - } - - private int getApiVersion(Element usesSdk, String attribute, int defaultApiLevel) { - String valueString = null; - if (usesSdk.hasAttributeNS(NS_RESOURCES, attribute)) { - valueString = usesSdk.getAttributeNS(NS_RESOURCES, attribute); - if (attribute.equals(ATTRIBUTE_MIN_SDK_VERSION)) { - mMinSdkName = valueString; - } - } - - if (valueString != null) { - int apiLevel = -1; - try { - apiLevel = Integer.valueOf(valueString); - } catch (NumberFormatException e) { - // Handle codename - if (Sdk.getCurrent() != null) { - IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString( - "android-" + valueString); //$NON-NLS-1$ - if (target != null) { - // codename future API level is current api + 1 - apiLevel = target.getVersion().getApiLevel() + 1; - } - } - } - - return apiLevel; - } - - return defaultApiLevel; - } - - /** - * Returns the default package registered in the Android manifest - * - * @return the default package registered in the manifest - */ - @NonNull - public String getPackage() { - sync(); - return mPackage; - } - - /** - * Returns a map from activity full class names to the corresponding {@link ActivityAttributes}. - * - * @return a map from activity fqcn to ActivityAttributes - */ - @NonNull - public Map<String, ActivityAttributes> getActivityAttributesMap() { - sync(); - return mActivityAttributes; - } - - /** - * Returns the attributes of an activity given its full class name. - */ - @Nullable - public ActivityAttributes getActivityAttributes(String activity) { - return getActivityAttributesMap().get(activity); - } - - /** - * Returns the manifest theme registered on the application, if any - * - * @return a manifest theme, or null if none was registered - */ - @Nullable - public String getManifestTheme() { - sync(); - return mManifestTheme; - } - - /** - * Returns the default theme for this project, by looking at the manifest default - * theme registration, target SDK, rendering target, etc. - * - * @param renderingTarget the rendering target use to render the theme, or null - * @param screenSize the screen size to obtain a default theme for, or null if unknown - * @return the theme to use for this project, never null - */ - @NonNull - public String getDefaultTheme(IAndroidTarget renderingTarget, ScreenSize screenSize) { - sync(); - - if (mManifestTheme != null) { - return mManifestTheme; - } - - int renderingTargetSdk = mTargetSdk; - if (renderingTarget != null) { - renderingTargetSdk = renderingTarget.getVersion().getApiLevel(); - } - - int apiLevel = Math.min(mTargetSdk, renderingTargetSdk); - // For now this theme works only on XLARGE screens. When it works for all sizes, - // add that new apiLevel to this check. - if (apiLevel >= 11 && screenSize == ScreenSize.XLARGE || apiLevel >= 14) { - return ANDROID_STYLE_RESOURCE_PREFIX + "Theme.Holo"; //$NON-NLS-1$ - } else { - return ANDROID_STYLE_RESOURCE_PREFIX + "Theme"; //$NON-NLS-1$ - } - } - - /** - * Returns the application icon, or null - * - * @return the application icon, or null - */ - @Nullable - public String getApplicationIcon() { - sync(); - return mApplicationIcon; - } - - /** - * Returns the application label, or null - * - * @return the application label, or null - */ - @Nullable - public String getApplicationLabel() { - sync(); - return mApplicationLabel; - } - - /** - * Returns true if the application has RTL support. - * - * @return true if the application has RTL support. - */ - public boolean isRtlSupported() { - sync(); - return mApplicationSupportsRtl; - } - - /** - * Returns the target SDK version - * - * @return the target SDK version - */ - public int getTargetSdkVersion() { - sync(); - return mTargetSdk; - } - - /** - * Returns the minimum SDK version - * - * @return the minimum SDK version - */ - public int getMinSdkVersion() { - sync(); - return mMinSdk; - } - - /** - * Returns the minimum SDK version name (which may not be a numeric string, e.g. - * it could be a codename). It will never be null or empty; if no min sdk version - * was specified in the manifest, the return value will be "1". Use - * {@link #getMinSdkCodeName()} instead if you want to look up whether there is a code name. - * - * @return the minimum SDK version - */ - @NonNull - public String getMinSdkName() { - sync(); - if (mMinSdkName == null || mMinSdkName.isEmpty()) { - mMinSdkName = "1"; //$NON-NLS-1$ - } - - return mMinSdkName; - } - - /** - * Returns the code name used for the minimum SDK version, if any. - * - * @return the minSdkVersion codename or null - */ - @Nullable - public String getMinSdkCodeName() { - String minSdkName = getMinSdkName(); - if (!Character.isDigit(minSdkName.charAt(0))) { - return minSdkName; - } - - return null; - } - - /** - * Returns the {@link IPackageFragment} for the package registered in the manifest - * - * @return the {@link IPackageFragment} for the package registered in the manifest - */ - @Nullable - public IPackageFragment getPackageFragment() { - sync(); - try { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); - if (javaProject != null) { - IPackageFragmentRoot root = ManifestInfo.getSourcePackageRoot(javaProject); - if (root != null) { - return root.getPackageFragment(mPackage); - } - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - - return null; - } - - /** - * Returns the activity associated with the given layout file. Makes an educated guess - * by peeking at the usages of the R.layout.name field corresponding to the layout and - * if it finds a usage. - * - * @param project the project containing the layout - * @param layoutName the layout whose activity we want to look up - * @param pkg the package containing activities - * @return the activity name - */ - @Nullable - public static String guessActivity(IProject project, String layoutName, String pkg) { - List<String> activities = guessActivities(project, layoutName, pkg); - if (activities.size() > 0) { - return activities.get(0); - } else { - return null; - } - } - - /** - * Returns the activities associated with the given layout file. Makes an educated guess - * by peeking at the usages of the R.layout.name field corresponding to the layout and - * if it finds a usage. - * - * @param project the project containing the layout - * @param layoutName the layout whose activity we want to look up - * @param pkg the package containing activities - * @return the activity name - */ - @NonNull - public static List<String> guessActivities(IProject project, String layoutName, String pkg) { - final LinkedList<String> activities = new LinkedList<String>(); - SearchRequestor requestor = new SearchRequestor() { - @Override - public void acceptSearchMatch(SearchMatch match) throws CoreException { - Object element = match.getElement(); - if (element instanceof IMethod) { - IMethod method = (IMethod) element; - IType declaringType = method.getDeclaringType(); - String fqcn = declaringType.getFullyQualifiedName(); - - if ((declaringType.getSuperclassName() != null && - declaringType.getSuperclassName().endsWith("Activity")) //$NON-NLS-1$ - || method.getElementName().equals("onCreate")) { //$NON-NLS-1$ - activities.addFirst(fqcn); - } else { - activities.addLast(fqcn); - } - } - } - }; - try { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - if (javaProject == null) { - return Collections.emptyList(); - } - // TODO - look around a bit more and see if we can figure out whether the - // call if from within a setContentView call! - - // Search for which java classes call setContentView(R.layout.layoutname); - String typeFqcn = "R.layout"; //$NON-NLS-1$ - if (pkg != null) { - typeFqcn = pkg + '.' + typeFqcn; - } - - IType type = javaProject.findType(typeFqcn); - if (type != null) { - IField field = type.getField(layoutName); - if (field.exists()) { - SearchPattern pattern = SearchPattern.createPattern(field, REFERENCES); - try { - search(requestor, javaProject, pattern); - } catch (OperationCanceledException canceled) { - // pass - } - } - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - - return activities; - } - - /** - * Returns all activities found in the given project (including those in libraries, - * except for android.jar itself) - * - * @param project the project - * @return a list of activity classes as fully qualified class names - */ - @SuppressWarnings("restriction") // BinaryType - @NonNull - public static List<String> getProjectActivities(IProject project) { - final List<String> activities = new ArrayList<String>(); - try { - final IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - if (javaProject != null) { - IType[] activityTypes = new IType[0]; - IType activityType = javaProject.findType(CLASS_ACTIVITY); - if (activityType != null) { - ITypeHierarchy hierarchy = - activityType.newTypeHierarchy(javaProject, new NullProgressMonitor()); - activityTypes = hierarchy.getAllSubtypes(activityType); - for (IType type : activityTypes) { - if (type instanceof BinaryType && (type.getClassFile() == null - || type.getClassFile().getResource() == null)) { - continue; - } - activities.add(type.getFullyQualifiedName()); - } - } - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - - return activities; - } - - - /** - * Returns the activity associated with the given layout file. - * <p> - * This is an alternative to {@link #guessActivity(IFile, String)}. Whereas - * guessActivity simply looks for references to "R.layout.foo", this method searches - * for all usages of Activity#setContentView(int), and for each match it looks up the - * corresponding call text (such as "setContentView(R.layout.foo)"). From this it uses - * a regexp to pull out "foo" from this, and stores the association that layout "foo" - * is associated with the activity class that contained the setContentView call. - * <p> - * This has two potential advantages: - * <ol> - * <li>It can be faster. We do the reference search -once-, and we've built a map of - * all the layout-to-activity mappings which we can then immediately look up other - * layouts for, which is particularly useful at startup when we have to compute the - * layout activity associations to populate the theme choosers. - * <li>It can be more accurate. Just because an activity references an "R.layout.foo" - * field doesn't mean it's setting it as a content view. - * </ol> - * However, this second advantage is also its chief problem. There are some common - * code constructs which means that the associated layout is not explicitly referenced - * in a direct setContentView call; on a couple of sample projects I tested I found - * patterns like for example "setContentView(v)" where "v" had been computed earlier. - * Therefore, for now we're going to stick with the more general approach of just - * looking up each field when needed. We're keeping the code around, though statically - * compiled out with the "if (false)" construct below in case we revisit this. - * - * @param layoutFile the layout whose activity we want to look up - * @return the activity name - */ - @SuppressWarnings("all") - @Nullable - public String guessActivityBySetContentView(String layoutName) { - if (false) { - // These should be fields - final Pattern LAYOUT_FIELD_PATTERN = - Pattern.compile("R\\.layout\\.([a-z0-9_]+)"); //$NON-NLS-1$ - Map<String, String> mUsages = null; - - sync(); - if (mUsages == null) { - final Map<String, String> usages = new HashMap<String, String>(); - mUsages = usages; - SearchRequestor requestor = new SearchRequestor() { - @Override - public void acceptSearchMatch(SearchMatch match) throws CoreException { - Object element = match.getElement(); - if (element instanceof IMethod) { - IMethod method = (IMethod) element; - IType declaringType = method.getDeclaringType(); - String fqcn = declaringType.getFullyQualifiedName(); - IDocumentProvider provider = new TextFileDocumentProvider(); - IResource resource = match.getResource(); - try { - provider.connect(resource); - IDocument document = provider.getDocument(resource); - if (document != null) { - String matchText = document.get(match.getOffset(), - match.getLength()); - Matcher matcher = LAYOUT_FIELD_PATTERN.matcher(matchText); - if (matcher.find()) { - usages.put(matcher.group(1), fqcn); - } - } - } catch (Exception e) { - AdtPlugin.log(e, "Can't find range information for %1$s", - resource.getName()); - } finally { - provider.disconnect(resource); - } - } - } - }; - try { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); - if (javaProject == null) { - return null; - } - - // Search for which java classes call setContentView(R.layout.layoutname); - String typeFqcn = "R.layout"; //$NON-NLS-1$ - if (mPackage != null) { - typeFqcn = mPackage + '.' + typeFqcn; - } - - IType activityType = javaProject.findType(CLASS_ACTIVITY); - if (activityType != null) { - IMethod method = activityType.getMethod( - "setContentView", new String[] {"I"}); //$NON-NLS-1$ //$NON-NLS-2$ - if (method.exists()) { - SearchPattern pattern = SearchPattern.createPattern(method, - REFERENCES); - search(requestor, javaProject, pattern); - } - } - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - } - - return mUsages.get(layoutName); - } - - return null; - } - - /** - * Performs a search using the given pattern, scope and handler. The search will abort - * if it takes longer than {@link #SEARCH_TIMEOUT_MS} milliseconds. - */ - private static void search(SearchRequestor requestor, IJavaProject javaProject, - SearchPattern pattern) throws CoreException { - // Find the package fragment specified in the manifest; the activities should - // live there. - IJavaSearchScope scope = createPackageScope(javaProject); - - SearchParticipant[] participants = new SearchParticipant[] { - SearchEngine.getDefaultSearchParticipant() - }; - SearchEngine engine = new SearchEngine(); - - final long searchStart = System.currentTimeMillis(); - NullProgressMonitor monitor = new NullProgressMonitor() { - private boolean mCancelled; - @Override - public void internalWorked(double work) { - long searchEnd = System.currentTimeMillis(); - if (searchEnd - searchStart > SEARCH_TIMEOUT_MS) { - mCancelled = true; - } - } - - @Override - public boolean isCanceled() { - return mCancelled; - } - }; - engine.search(pattern, participants, scope, requestor, monitor); - } - - /** Creates a package search scope for the first package root in the given java project */ - private static IJavaSearchScope createPackageScope(IJavaProject javaProject) { - IPackageFragmentRoot packageRoot = getSourcePackageRoot(javaProject); - - IJavaSearchScope scope; - if (packageRoot != null) { - IJavaElement[] scopeElements = new IJavaElement[] { packageRoot }; - scope = SearchEngine.createJavaSearchScope(scopeElements); - } else { - scope = SearchEngine.createWorkspaceScope(); - } - return scope; - } - - /** - * Returns the first package root for the given java project - * - * @param javaProject the project to search in - * @return the first package root, or null - */ - @Nullable - public static IPackageFragmentRoot getSourcePackageRoot(IJavaProject javaProject) { - IPackageFragmentRoot packageRoot = null; - List<IPath> sources = BaseProjectHelper.getSourceClasspaths(javaProject); - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - for (IPath path : sources) { - IResource firstSource = workspace.getRoot().findMember(path); - if (firstSource != null) { - packageRoot = javaProject.getPackageFragmentRoot(firstSource); - if (packageRoot != null) { - break; - } - } - } - return packageRoot; - } - - /** - * Computes the minimum SDK and target SDK versions for the project - * - * @param project the project to look up the versions for - * @return a pair of (minimum SDK, target SDK) versions, never null - */ - @NonNull - public static Pair<Integer, Integer> computeSdkVersions(IProject project) { - int mMinSdkVersion = 1; - int mTargetSdkVersion = 1; - - IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project)); - if (manifestFile != null) { - try { - Object value = AndroidManifest.getMinSdkVersion(manifestFile); - mMinSdkVersion = 1; // Default case if missing - if (value instanceof Integer) { - mMinSdkVersion = ((Integer) value).intValue(); - } else if (value instanceof String) { - // handle codename, only if we can resolve it. - if (Sdk.getCurrent() != null) { - IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString( - "android-" + value); //$NON-NLS-1$ - if (target != null) { - // codename future API level is current api + 1 - mMinSdkVersion = target.getVersion().getApiLevel() + 1; - } - } - } - - value = AndroidManifest.getTargetSdkVersion(manifestFile); - if (value == null) { - mTargetSdkVersion = mMinSdkVersion; - } else if (value instanceof String) { - // handle codename, only if we can resolve it. - if (Sdk.getCurrent() != null) { - IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString( - "android-" + value); //$NON-NLS-1$ - if (target != null) { - // codename future API level is current api + 1 - mTargetSdkVersion = target.getVersion().getApiLevel() + 1; - } - } - } - } catch (XPathExpressionException e) { - // do nothing we'll use 1 below. - } catch (StreamException e) { - // do nothing we'll use 1 below. - } - } - - return Pair.of(mMinSdkVersion, mTargetSdkVersion); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java deleted file mode 100644 index a3d398657..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.editors.manifest; - - -import com.android.ide.eclipse.adt.internal.editors.AndroidSourceViewerConfig; - -import org.eclipse.jface.text.contentassist.IContentAssistProcessor; -import org.eclipse.jface.text.source.ISourceViewer; - -/** - * Source Viewer Configuration that calls in ManifestContentAssist. - */ -public final class ManifestSourceViewerConfig extends AndroidSourceViewerConfig { - - private ManifestContentAssist mAndroidContentAssist; - - public ManifestSourceViewerConfig() { - super(); - mAndroidContentAssist = new ManifestContentAssist(); - } - - @Override - public IContentAssistProcessor getAndroidContentAssistProcessor( - ISourceViewer sourceViewer, - String partitionType) { - return mAndroidContentAssist; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java deleted file mode 100644 index 3429e43a0..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.SdkConstants; -import com.android.ide.common.api.IAttributeInfo; -import com.android.ide.common.api.IAttributeInfo.Format; -import com.android.ide.common.resources.platform.AttributeInfo; -import com.android.ide.common.resources.platform.AttrsXmlParser; -import com.android.ide.common.resources.platform.DeclareStyleableInfo; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor.Mandatory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ITextAttributeCreator; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ListAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; - -import org.eclipse.core.runtime.IStatus; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; - - -/** - * Complete description of the AndroidManifest.xml structure. - * <p/> - * The root element are static instances which always exists. - * However their sub-elements and attributes are created only when the SDK changes or is - * loaded the first time. - */ -public final class AndroidManifestDescriptors implements IDescriptorProvider { - /** Name of the {@code <uses-permission>} */ - public static final String USES_PERMISSION = "uses-permission"; //$NON-NLS-1$ - private static final String MANIFEST_NODE_NAME = "manifest"; //$NON-NLS-1$ - private static final String ANDROID_MANIFEST_STYLEABLE = - AttrsXmlParser.ANDROID_MANIFEST_STYLEABLE; - - // Public attributes names, attributes descriptors and elements descriptors - - public static final String ANDROID_LABEL_ATTR = "label"; //$NON-NLS-1$ - public static final String ANDROID_NAME_ATTR = "name"; //$NON-NLS-1$ - public static final String PACKAGE_ATTR = "package"; //$NON-NLS-1$ - - /** The {@link ElementDescriptor} for the root Manifest element. */ - private final ElementDescriptor MANIFEST_ELEMENT; - /** The {@link ElementDescriptor} for the root Application element. */ - private final ElementDescriptor APPLICATION_ELEMENT; - - /** The {@link ElementDescriptor} for the root Instrumentation element. */ - private final ElementDescriptor INTRUMENTATION_ELEMENT; - /** The {@link ElementDescriptor} for the root Permission element. */ - private final ElementDescriptor PERMISSION_ELEMENT; - /** The {@link ElementDescriptor} for the root UsesPermission element. */ - private final ElementDescriptor USES_PERMISSION_ELEMENT; - /** The {@link ElementDescriptor} for the root UsesSdk element. */ - private final ElementDescriptor USES_SDK_ELEMENT; - - /** The {@link ElementDescriptor} for the root PermissionGroup element. */ - private final ElementDescriptor PERMISSION_GROUP_ELEMENT; - /** The {@link ElementDescriptor} for the root PermissionTree element. */ - private final ElementDescriptor PERMISSION_TREE_ELEMENT; - - /** Private package attribute for the manifest element. Needs to be handled manually. */ - private final TextAttributeDescriptor PACKAGE_ATTR_DESC; - - public AndroidManifestDescriptors() { - APPLICATION_ELEMENT = createElement("application", null, Mandatory.MANDATORY_LAST); //$NON-NLS-1$ + no child & mandatory - INTRUMENTATION_ELEMENT = createElement("instrumentation"); //$NON-NLS-1$ - - PERMISSION_ELEMENT = createElement("permission"); //$NON-NLS-1$ - USES_PERMISSION_ELEMENT = createElement(USES_PERMISSION); - USES_SDK_ELEMENT = createElement("uses-sdk", null, Mandatory.MANDATORY); //$NON-NLS-1$ + no child & mandatory - - PERMISSION_GROUP_ELEMENT = createElement("permission-group"); //$NON-NLS-1$ - PERMISSION_TREE_ELEMENT = createElement("permission-tree"); //$NON-NLS-1$ - - MANIFEST_ELEMENT = createElement( - MANIFEST_NODE_NAME, // xml name - new ElementDescriptor[] { - APPLICATION_ELEMENT, - INTRUMENTATION_ELEMENT, - PERMISSION_ELEMENT, - USES_PERMISSION_ELEMENT, - PERMISSION_GROUP_ELEMENT, - PERMISSION_TREE_ELEMENT, - USES_SDK_ELEMENT, - }, - Mandatory.MANDATORY); - - // The "package" attribute is treated differently as it doesn't have the standard - // Android XML namespace. - PACKAGE_ATTR_DESC = new PackageAttributeDescriptor(PACKAGE_ATTR, - null /* nsUri */, - new AttributeInfo(PACKAGE_ATTR, Format.REFERENCE_SET)).setTooltip( - "This attribute gives a unique name for the package, using a Java-style " + - "naming convention to avoid name collisions.\nFor example, applications " + - "published by Google could have names of the form com.google.app.appname"); - } - - @Override - public ElementDescriptor[] getRootElementDescriptors() { - return new ElementDescriptor[] { MANIFEST_ELEMENT }; - } - - @Override - public ElementDescriptor getDescriptor() { - return getManifestElement(); - } - - public ElementDescriptor getApplicationElement() { - return APPLICATION_ELEMENT; - } - - public ElementDescriptor getManifestElement() { - return MANIFEST_ELEMENT; - } - - public ElementDescriptor getUsesSdkElement() { - return USES_SDK_ELEMENT; - } - - public ElementDescriptor getInstrumentationElement() { - return INTRUMENTATION_ELEMENT; - } - - public ElementDescriptor getPermissionElement() { - return PERMISSION_ELEMENT; - } - - public ElementDescriptor getUsesPermissionElement() { - return USES_PERMISSION_ELEMENT; - } - - public ElementDescriptor getPermissionGroupElement() { - return PERMISSION_GROUP_ELEMENT; - } - - public ElementDescriptor getPermissionTreeElement() { - return PERMISSION_TREE_ELEMENT; - } - - /** - * Updates the document descriptor. - * <p/> - * It first computes the new children of the descriptor and then updates them - * all at once. - * - * @param manifestMap The map style => attributes from the attrs_manifest.xml file - */ - public synchronized void updateDescriptors( - Map<String, DeclareStyleableInfo> manifestMap) { - - // -- setup the required attributes overrides -- - - Set<String> required = new HashSet<String>(); - required.add("provider/authorities"); //$NON-NLS-1$ - - // -- setup the various attribute format overrides -- - - // The key for each override is "element1,element2,.../attr-xml-local-name" or - // "*/attr-xml-local-name" to match the attribute in any element. - - Map<String, ITextAttributeCreator> overrides = new HashMap<String, ITextAttributeCreator>(); - - overrides.put("*/icon", ReferenceAttributeDescriptor.CREATOR); //$NON-NLS-1$ - - overrides.put("*/theme", ThemeAttributeDescriptor.CREATOR); //$NON-NLS-1$ - overrides.put("*/permission", ListAttributeDescriptor.CREATOR); //$NON-NLS-1$ - overrides.put("*/targetPackage", ManifestPkgAttrDescriptor.CREATOR); //$NON-NLS-1$ - - overrides.put("uses-library/name", ListAttributeDescriptor.CREATOR); //$NON-NLS-1$ - overrides.put("action,category,uses-permission/" + ANDROID_NAME_ATTR, //$NON-NLS-1$ - ListAttributeDescriptor.CREATOR); - - overrideClassName(overrides, "application", //$NON-NLS-1$ - SdkConstants.CLASS_APPLICATION, - false /*mandatory*/); - overrideClassName(overrides, "application/backupAgent", //$NON-NLS-1$ - "android.app.backup.BackupAgent", //$NON-NLS-1$ - false /*mandatory*/); - overrideClassName(overrides, "activity", SdkConstants.CLASS_ACTIVITY); //$NON-NLS-1$ - overrideClassName(overrides, "receiver", SdkConstants.CLASS_BROADCASTRECEIVER);//$NON-NLS-1$ - overrideClassName(overrides, "service", SdkConstants.CLASS_SERVICE); //$NON-NLS-1$ - overrideClassName(overrides, "provider", SdkConstants.CLASS_CONTENTPROVIDER); //$NON-NLS-1$ - overrideClassName(overrides, "instrumentation", - SdkConstants.CLASS_INSTRUMENTATION); //$NON-NLS-1$ - - // -- list element nodes already created -- - // These elements are referenced by already opened editors, so we want to update them - // but not re-create them when reloading an SDK on the fly. - - HashMap<String, ElementDescriptor> elementDescs = - new HashMap<String, ElementDescriptor>(); - elementDescs.put(MANIFEST_ELEMENT.getXmlLocalName(), MANIFEST_ELEMENT); - elementDescs.put(APPLICATION_ELEMENT.getXmlLocalName(), APPLICATION_ELEMENT); - elementDescs.put(INTRUMENTATION_ELEMENT.getXmlLocalName(), INTRUMENTATION_ELEMENT); - elementDescs.put(PERMISSION_ELEMENT.getXmlLocalName(), PERMISSION_ELEMENT); - elementDescs.put(USES_PERMISSION_ELEMENT.getXmlLocalName(), USES_PERMISSION_ELEMENT); - elementDescs.put(USES_SDK_ELEMENT.getXmlLocalName(), USES_SDK_ELEMENT); - elementDescs.put(PERMISSION_GROUP_ELEMENT.getXmlLocalName(), PERMISSION_GROUP_ELEMENT); - elementDescs.put(PERMISSION_TREE_ELEMENT.getXmlLocalName(), PERMISSION_TREE_ELEMENT); - - // -- - - inflateElement(manifestMap, - overrides, - required, - elementDescs, - MANIFEST_ELEMENT, - "AndroidManifest"); //$NON-NLS-1$ - insertAttribute(MANIFEST_ELEMENT, PACKAGE_ATTR_DESC); - - XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor( - SdkConstants.ANDROID_NS_NAME, SdkConstants.ANDROID_URI); - insertAttribute(MANIFEST_ELEMENT, xmlns); - - /* - * - * - */ - assert sanityCheck(manifestMap, MANIFEST_ELEMENT); - } - - /** - * Sets up a mandatory attribute override using a ClassAttributeDescriptor - * with the specified class name. - * - * @param overrides The current map of overrides. - * @param elementName The element name to override, e.g. "application". - * If this name does NOT have a slash (/), the ANDROID_NAME_ATTR attribute will be overriden. - * Otherwise, if it contains a (/) the format is "element/attribute", for example - * "application/name" vs "application/backupAgent". - * @param className The fully qualified name of the base class of the attribute. - */ - private static void overrideClassName( - Map<String, ITextAttributeCreator> overrides, - String elementName, - final String className) { - overrideClassName(overrides, elementName, className, true); - } - - /** - * Sets up an attribute override using a ClassAttributeDescriptor - * with the specified class name. - * - * @param overrides The current map of overrides. - * @param elementName The element name to override, e.g. "application". - * If this name does NOT have a slash (/), the ANDROID_NAME_ATTR attribute will be overriden. - * Otherwise, if it contains a (/) the format is "element/attribute", for example - * "application/name" vs "application/backupAgent". - * @param className The fully qualified name of the base class of the attribute. - * @param mandatory True if this attribute is mandatory, false if optional. - */ - private static void overrideClassName( - Map<String, ITextAttributeCreator> overrides, - String elementName, - final String className, - final boolean mandatory) { - if (elementName.indexOf('/') == -1) { - elementName = elementName + '/' + ANDROID_NAME_ATTR; - } - overrides.put(elementName, - new ITextAttributeCreator() { - @Override - public TextAttributeDescriptor create(String xmlName, String nsUri, - IAttributeInfo attrInfo) { - if (attrInfo == null) { - attrInfo = new AttributeInfo(xmlName, Format.STRING_SET ); - } - - if (SdkConstants.CLASS_ACTIVITY.equals(className)) { - return new ClassAttributeDescriptor( - className, - PostActivityCreationAction.getAction(), - xmlName, - nsUri, - attrInfo, - mandatory, - true /*defaultToProjectOnly*/); - } else if (SdkConstants.CLASS_BROADCASTRECEIVER.equals(className)) { - return new ClassAttributeDescriptor( - className, - PostReceiverCreationAction.getAction(), - xmlName, - nsUri, - attrInfo, - mandatory, - true /*defaultToProjectOnly*/); - } else if (SdkConstants.CLASS_INSTRUMENTATION.equals(className)) { - return new ClassAttributeDescriptor( - className, - null, // no post action - xmlName, - nsUri, - attrInfo, - mandatory, - false /*defaultToProjectOnly*/); - } else { - return new ClassAttributeDescriptor( - className, - xmlName, - nsUri, - attrInfo, - mandatory); - } - } - }); - } - - /** - * Returns a new ElementDescriptor constructed from the information given here - * and the javadoc & attributes extracted from the style map if any. - * <p/> - * Creates an element with no attribute overrides. - */ - private ElementDescriptor createElement( - String xmlName, - ElementDescriptor[] childrenElements, - Mandatory mandatory) { - // Creates an element with no attribute overrides. - String styleName = guessStyleName(xmlName); - String sdkUrl = DescriptorsUtils.MANIFEST_SDK_URL + styleName; - String uiName = getUiName(xmlName); - - ElementDescriptor element = new ManifestElementDescriptor(xmlName, uiName, null, sdkUrl, - null, childrenElements, mandatory); - - return element; - } - - /** - * Returns a new ElementDescriptor constructed from its XML local name. - * <p/> - * This version creates an element not mandatory. - */ - private ElementDescriptor createElement(String xmlName) { - // Creates an element with no child and not mandatory - return createElement(xmlName, null, Mandatory.NOT_MANDATORY); - } - - /** - * Inserts an attribute in this element attribute list if it is not present there yet - * (based on the attribute XML name.) - * The attribute is inserted at the beginning of the attribute list. - */ - private void insertAttribute(ElementDescriptor element, AttributeDescriptor newAttr) { - AttributeDescriptor[] attributes = element.getAttributes(); - for (AttributeDescriptor attr : attributes) { - if (attr.getXmlLocalName().equals(newAttr.getXmlLocalName())) { - return; - } - } - - AttributeDescriptor[] newArray = new AttributeDescriptor[attributes.length + 1]; - newArray[0] = newAttr; - System.arraycopy(attributes, 0, newArray, 1, attributes.length); - element.setAttributes(newArray); - } - - /** - * "Inflates" the properties of an {@link ElementDescriptor} from the styleable declaration. - * <p/> - * This first creates all the attributes for the given ElementDescriptor. - * It then finds all children of the descriptor, inflates them recursively and sets them - * as child to this ElementDescriptor. - * - * @param styleMap The input styleable map for manifest elements & attributes. - * @param overrides A list of attribute overrides (to customize the type of the attribute - * descriptors). - * @param requiredAttributes Set of attributes to be marked as required. - * @param existingElementDescs A map of already created element descriptors, keyed by - * XML local name. This is used to use the static elements created initially by this - * class, which are referenced directly by editors (so that reloading an SDK won't - * break these references). - * @param elemDesc The current {@link ElementDescriptor} to inflate. - * @param styleName The name of the {@link ElementDescriptor} to inflate. Its XML local name - * will be guessed automatically from the style name. - */ - private void inflateElement( - Map<String, DeclareStyleableInfo> styleMap, - Map<String, ITextAttributeCreator> overrides, - Set<String> requiredAttributes, - HashMap<String, ElementDescriptor> existingElementDescs, - ElementDescriptor elemDesc, - String styleName) { - assert elemDesc != null; - assert styleName != null; - assert styleMap != null; - - if (styleMap == null) { - return; - } - - // define attributes - DeclareStyleableInfo style = styleMap.get(styleName); - if (style != null) { - ArrayList<AttributeDescriptor> attrDescs = new ArrayList<AttributeDescriptor>(); - DescriptorsUtils.appendAttributes(attrDescs, - elemDesc.getXmlLocalName(), - SdkConstants.NS_RESOURCES, - style.getAttributes(), - requiredAttributes, - overrides); - elemDesc.setTooltip(style.getJavaDoc()); - elemDesc.setAttributes(attrDescs.toArray(new AttributeDescriptor[attrDescs.size()])); - } - - // find all elements that have this one as parent - ArrayList<ElementDescriptor> children = new ArrayList<ElementDescriptor>(); - for (Entry<String, DeclareStyleableInfo> entry : styleMap.entrySet()) { - DeclareStyleableInfo childStyle = entry.getValue(); - boolean isParent = false; - String[] parents = childStyle.getParents(); - if (parents != null) { - for (String parent: parents) { - if (styleName.equals(parent)) { - isParent = true; - break; - } - } - } - if (isParent) { - String childStyleName = entry.getKey(); - String childXmlName = guessXmlName(childStyleName); - - // create or re-use element - ElementDescriptor child = existingElementDescs.get(childXmlName); - if (child == null) { - child = createElement(childXmlName); - existingElementDescs.put(childXmlName, child); - } - children.add(child); - - inflateElement(styleMap, - overrides, - requiredAttributes, - existingElementDescs, - child, - childStyleName); - } - } - elemDesc.setChildren(children.toArray(new ElementDescriptor[children.size()])); - } - - /** - * Get an UI name from the element XML name. - * <p/> - * Capitalizes the first letter and replace non-alphabet by a space followed by a capital. - */ - private static String getUiName(String xmlName) { - StringBuilder sb = new StringBuilder(); - - boolean capitalize = true; - for (char c : xmlName.toCharArray()) { - if (capitalize && c >= 'a' && c <= 'z') { - sb.append((char)(c + 'A' - 'a')); - capitalize = false; - } else if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { - sb.append(' '); - capitalize = true; - } else { - sb.append(c); - } - } - - return sb.toString(); - } - - /** - * Guesses the style name for a given XML element name. - * <p/> - * The rules are: - * - capitalize the first letter: - * - if there's a dash, skip it and capitalize the next one - * - prefix AndroidManifest - * The exception is "manifest" which just becomes AndroidManifest. - * <p/> - * Examples: - * - manifest => AndroidManifest - * - application => AndroidManifestApplication - * - uses-permission => AndroidManifestUsesPermission - */ - private String guessStyleName(String xmlName) { - StringBuilder sb = new StringBuilder(); - - if (!xmlName.equals(MANIFEST_NODE_NAME)) { - boolean capitalize = true; - for (char c : xmlName.toCharArray()) { - if (capitalize && c >= 'a' && c <= 'z') { - sb.append((char)(c + 'A' - 'a')); - capitalize = false; - } else if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { - // not a letter -- skip the character and capitalize the next one - capitalize = true; - } else { - sb.append(c); - } - } - } - - sb.insert(0, ANDROID_MANIFEST_STYLEABLE); - return sb.toString(); - } - - /** - * This method performs a sanity check to make sure all the styles declared in the - * manifestMap are actually defined in the actual element descriptors and reachable from - * the manifestElement root node. - */ - private boolean sanityCheck(Map<String, DeclareStyleableInfo> manifestMap, - ElementDescriptor manifestElement) { - TreeSet<String> elementsDeclared = new TreeSet<String>(); - findAllElementNames(manifestElement, elementsDeclared); - - TreeSet<String> stylesDeclared = new TreeSet<String>(); - for (String styleName : manifestMap.keySet()) { - if (styleName.startsWith(ANDROID_MANIFEST_STYLEABLE)) { - stylesDeclared.add(styleName); - } - } - - for (Iterator<String> it = elementsDeclared.iterator(); it.hasNext();) { - String xmlName = it.next(); - String styleName = guessStyleName(xmlName); - if (stylesDeclared.remove(styleName)) { - it.remove(); - } - } - - StringBuilder sb = new StringBuilder(); - if (!stylesDeclared.isEmpty()) { - sb.append("Warning, ADT/SDK Mismatch! The following elements are declared by the SDK but unknown to ADT: "); - for (String name : stylesDeclared) { - sb.append(guessXmlName(name)); - - if (!name.equals(stylesDeclared.last())) { - sb.append(", "); //$NON-NLS-1$ - } - } - - AdtPlugin.log(IStatus.WARNING, "%s", sb.toString()); - AdtPlugin.printToConsole((String)null, sb); - sb.setLength(0); - } - - if (!elementsDeclared.isEmpty()) { - sb.append("Warning, ADT/SDK Mismatch! The following elements are declared by ADT but not by the SDK: "); - for (String name : elementsDeclared) { - sb.append(name); - if (!name.equals(elementsDeclared.last())) { - sb.append(", "); //$NON-NLS-1$ - } - } - - AdtPlugin.log(IStatus.WARNING, "%s", sb.toString()); - AdtPlugin.printToConsole((String)null, sb); - } - - return true; - } - - /** - * Performs an approximate translation of the style name into a potential - * xml name. This is more or less the reverse from guessStyleName(). - * - * @return The XML local name for a given style name. - */ - private String guessXmlName(String name) { - StringBuilder sb = new StringBuilder(); - if (ANDROID_MANIFEST_STYLEABLE.equals(name)) { - sb.append(MANIFEST_NODE_NAME); - } else { - name = name.replace(ANDROID_MANIFEST_STYLEABLE, ""); //$NON-NLS-1$ - boolean first_char = true; - for (char c : name.toCharArray()) { - if (c >= 'A' && c <= 'Z') { - if (!first_char) { - sb.append('-'); - } - c = (char) (c - 'A' + 'a'); - } - sb.append(c); - first_char = false; - } - } - return sb.toString(); - } - - /** - * Helper method used by {@link #sanityCheck(Map, ElementDescriptor)} to find all the - * {@link ElementDescriptor} names defined by the tree of descriptors. - * <p/> - * Note: this assumes no circular reference in the tree of {@link ElementDescriptor}s. - */ - private void findAllElementNames(ElementDescriptor element, TreeSet<String> declared) { - declared.add(element.getXmlName()); - for (ElementDescriptor desc : element.getChildren()) { - findAllElementNames(desc, declared); - } - } - - -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java deleted file mode 100644 index 1a27f8d00..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.SdkConstants; -import com.android.ide.common.api.IAttributeInfo; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -/** - * Describes an XML attribute representing a class name. - * It is displayed by a {@link UiClassAttributeNode}. - */ -public class ClassAttributeDescriptor extends TextAttributeDescriptor { - - /** Superclass of the class value. */ - private String mSuperClassName; - - private IPostTypeCreationAction mPostCreationAction; - - /** indicates if the class parameter is mandatory */ - boolean mMandatory; - - private final boolean mDefaultToProjectOnly; - - /** - * Creates a new {@link ClassAttributeDescriptor} - * @param superClassName the fully qualified name of the superclass of the class represented - * by the attribute. - * @param xmlLocalName The XML name of the attribute (case sensitive, with android: prefix). - * @param nsUri The URI of the attribute. Can be null if attribute has no namespace. - * See {@link SdkConstants#NS_RESOURCES} for a common value. - * @param attrInfo The {@link IAttributeInfo} of this attribute. Can't be null. - * @param mandatory indicates if the class attribute is mandatory. - */ - public ClassAttributeDescriptor(String superClassName, - String xmlLocalName, - String nsUri, - IAttributeInfo attrInfo, - boolean mandatory) { - super(xmlLocalName, nsUri, attrInfo); - mSuperClassName = superClassName; - mDefaultToProjectOnly = true; - if (mandatory) { - mMandatory = true; - setRequired(true); - } - } - - /** - * Creates a new {@link ClassAttributeDescriptor} - * @param superClassName the fully qualified name of the superclass of the class represented - * by the attribute. - * @param postCreationAction the {@link IPostTypeCreationAction} to be executed on the - * newly created class. - * @param xmlLocalName The XML local name of the attribute (case sensitive). - * @param nsUri The URI of the attribute. Can be null if attribute has no namespace. - * See {@link SdkConstants#NS_RESOURCES} for a common value. - * @param attrInfo The {@link IAttributeInfo} of this attribute. Can't be null. - * @param mandatory indicates if the class attribute is mandatory. - * @param defaultToProjectOnly True if only classes from the sources of this project should - * be shown by default in the class browser. - */ - public ClassAttributeDescriptor(String superClassName, - IPostTypeCreationAction postCreationAction, - String xmlLocalName, - String nsUri, - IAttributeInfo attrInfo, - boolean mandatory, - boolean defaultToProjectOnly) { - super(xmlLocalName, nsUri, attrInfo); - mSuperClassName = superClassName; - mPostCreationAction = postCreationAction; - mDefaultToProjectOnly = defaultToProjectOnly; - if (mandatory) { - mMandatory = true; - setRequired(true); - } - } - - /** - * @return A new {@link UiClassAttributeNode} linked to this descriptor. - */ - @Override - public UiAttributeNode createUiNode(UiElementNode uiParent) { - return new UiClassAttributeNode(mSuperClassName, mPostCreationAction, - mMandatory, this, uiParent, mDefaultToProjectOnly); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java deleted file mode 100644 index deb815e57..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiManifestElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -/** - * {@link ManifestElementDescriptor} describes an XML element node, with its - * element name, its possible attributes, its possible child elements but also - * its display name and tooltip. - * - * This {@link ElementDescriptor} is specialized to create {@link UiManifestElementNode} UI nodes. - */ -public class ManifestElementDescriptor extends ElementDescriptor { - - /** - * Constructs a new {@link ManifestElementDescriptor}. - * - * @param xml_name The XML element node name. Case sensitive. - * @param ui_name The XML element name for the user interface, typically capitalized. - * @param tooltip An optional tooltip. Can be null or empty. - * @param sdk_url An optional SKD URL. Can be null or empty. - * @param attributes The list of allowed attributes. Can be null or empty. - * @param children The list of allowed children. Can be null or empty. - * @param mandatory Whether this node must always exist (even for empty models). - */ - public ManifestElementDescriptor(String xml_name, - String ui_name, - String tooltip, - String sdk_url, - AttributeDescriptor[] attributes, - ElementDescriptor[] children, - Mandatory mandatory) { - super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory); - } - - /** - * Constructs a new {@link ManifestElementDescriptor}. - * - * @param xml_name The XML element node name. Case sensitive. - * @param ui_name The XML element name for the user interface, typically capitalized. - * @param tooltip An optional tooltip. Can be null or empty. - * @param sdk_url An optional SKD URL. Can be null or empty. - * @param attributes The list of allowed attributes. Can be null or empty. - * @param children The list of allowed children. Can be null or empty. - * @param mandatory Whether this node must always exist (even for empty models). - */ - public ManifestElementDescriptor(String xml_name, - String ui_name, - String tooltip, - String sdk_url, - AttributeDescriptor[] attributes, - ElementDescriptor[] children, - boolean mandatory) { - super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory); - } - - /** - * Constructs a new {@link ManifestElementDescriptor}. - * - * @param xml_name The XML element node name. Case sensitive. - * @param ui_name The XML element name for the user interface, typically capitalized. - * @param tooltip An optional tooltip. Can be null or empty. - * @param sdk_url An optional SKD URL. Can be null or empty. - * @param attributes The list of allowed attributes. Can be null or empty. - * @param children The list of allowed children. Can be null or empty. - */ - public ManifestElementDescriptor(String xml_name, - String ui_name, - String tooltip, - String sdk_url, - AttributeDescriptor[] attributes, - ElementDescriptor[] children) { - super(xml_name, ui_name, tooltip, sdk_url, attributes, children, false); - } - - /** - * This is a shortcut for - * ManifestElementDescriptor(xml_name, xml_name.capitalize(), null, null, null, children). - * This constructor is mostly used for unit tests. - * - * @param xml_name The XML element node name. Case sensitive. - */ - public ManifestElementDescriptor(String xml_name, ElementDescriptor[] children) { - super(xml_name, children); - } - - /** - * This is a shortcut for - * ManifestElementDescriptor(xml_name, xml_name.capitalize(), null, null, null, null). - * This constructor is mostly used for unit tests. - * - * @param xml_name The XML element node name. Case sensitive. - */ - public ManifestElementDescriptor(String xml_name) { - super(xml_name, null); - } - - /** - * @return A new {@link UiElementNode} linked to this descriptor. - */ - @Override - public UiElementNode createUiNode() { - return new UiManifestElementNode(this); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java deleted file mode 100755 index 74b789487..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2009 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.editors.manifest.descriptors; - -import com.android.ide.common.api.IAttributeInfo; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ITextAttributeCreator; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiManifestPkgAttrNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -/** - * Describes a package XML attribute. It is displayed by a {@link UiManifestPkgAttrNode}. - * <p/> - * Used by the override for .../targetPackage in {@link AndroidManifestDescriptors}. - */ -public class ManifestPkgAttrDescriptor extends TextAttributeDescriptor { - - /** - * Used by {@link DescriptorsUtils} to create instances of this descriptor. - */ - public static final ITextAttributeCreator CREATOR = new ITextAttributeCreator() { - @Override - public TextAttributeDescriptor create(String xmlLocalName, - String nsUri, IAttributeInfo attrInfo) { - return new ManifestPkgAttrDescriptor(xmlLocalName, nsUri, attrInfo); - } - }; - - public ManifestPkgAttrDescriptor(String xmlLocalName, String nsUri, IAttributeInfo attrInfo) { - super(xmlLocalName, nsUri, attrInfo); - } - - /** - * @return A new {@link UiManifestPkgAttrNode} linked to this descriptor. - */ - @Override - public UiAttributeNode createUiNode(UiElementNode uiParent) { - return new UiManifestPkgAttrNode(this, uiParent); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java deleted file mode 100644 index e8395ac40..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.ide.common.api.IAttributeInfo; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiPackageAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -/** - * Describes a package XML attribute. It is displayed by a {@link UiPackageAttributeNode}. - */ -public class PackageAttributeDescriptor extends TextAttributeDescriptor { - - public PackageAttributeDescriptor(String xmlLocalName, String nsUri, IAttributeInfo attrInfo) { - super(xmlLocalName, nsUri, attrInfo); - } - - /** - * @return A new {@link UiPackageAttributeNode} linked to this descriptor. - */ - @Override - public UiAttributeNode createUiNode(UiElementNode uiParent) { - return new UiPackageAttributeNode(this, uiParent); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java deleted file mode 100644 index 60c663dfc..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaModelException; - -/** - * Action to be executed after an Activity class is created. - */ -class PostActivityCreationAction implements IPostTypeCreationAction { - - private final static PostActivityCreationAction sAction = new PostActivityCreationAction(); - - private PostActivityCreationAction() { - // private constructor to enforce singleton. - } - - - /** - * Returns the action. - */ - public static IPostTypeCreationAction getAction() { - return sAction; - } - - /** - * Processes a newly created Activity. - * - */ - @Override - public void processNewType(IType newType) { - try { - String methodContent = - " /** Called when the activity is first created. */\n" + - " @Override\n" + - " public void onCreate(Bundle savedInstanceState) {\n" + - " super.onCreate(savedInstanceState);\n" + - "\n" + - " // TODO Auto-generated method stub\n" + - " }"; - newType.createMethod(methodContent, null /* sibling*/, false /* force */, - new NullProgressMonitor()); - - // we need to add the import for Bundle, so we need the compilation unit. - // Since the type could be enclosed in other types, we loop till we find it. - ICompilationUnit compilationUnit = null; - IJavaElement element = newType; - do { - IJavaElement parentElement = element.getParent(); - if (parentElement != null) { - if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { - compilationUnit = (ICompilationUnit)parentElement; - } - - element = parentElement; - } else { - break; - } - } while (compilationUnit == null); - - if (compilationUnit != null) { - compilationUnit.createImport(SdkConstants.CLASS_BUNDLE, - null /* sibling */, new NullProgressMonitor()); - } - } catch (JavaModelException e) { - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java deleted file mode 100644 index 8b2c36144..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.internal.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaModelException; - -/** - * Action to be executed after an BroadcastReceiver class is created. - */ -class PostReceiverCreationAction implements IPostTypeCreationAction { - - private final static PostReceiverCreationAction sAction = new PostReceiverCreationAction(); - - private PostReceiverCreationAction() { - // private constructor to enforce singleton. - } - - /** - * Returns the action. - */ - public static IPostTypeCreationAction getAction() { - return sAction; - } - - /** - * Processes a newly created Activity. - * - */ - @Override - public void processNewType(IType newType) { - try { - String methodContent = - " @Override\n" + - " public void onReceive(Context context, Intent intent) {\n" + - " // TODO Auto-generated method stub\n" + - " }"; - newType.createMethod(methodContent, null /* sibling*/, false /* force */, - new NullProgressMonitor()); - - // we need to add the import for Bundle, so we need the compilation unit. - // Since the type could be enclosed in other types, we loop till we find it. - ICompilationUnit compilationUnit = null; - IJavaElement element = newType; - do { - IJavaElement parentElement = element.getParent(); - if (parentElement != null) { - if (parentElement.getElementType() == IJavaElement.COMPILATION_UNIT) { - compilationUnit = (ICompilationUnit)parentElement; - } - - element = parentElement; - } else { - break; - } - } while (compilationUnit == null); - - if (compilationUnit != null) { - compilationUnit.createImport(SdkConstants.CLASS_CONTEXT, - null /* sibling */, new NullProgressMonitor()); - compilationUnit.createImport(SdkConstants.CLASS_INTENT, - null /* sibling */, new NullProgressMonitor()); - } - } catch (JavaModelException e) { - // looks like the class already existed (this happens when the user check to create - // inherited abstract methods). - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java deleted file mode 100644 index 881d75361..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.editors.manifest.descriptors; - -import com.android.ide.common.api.IAttributeInfo; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ITextAttributeCreator; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode; -import com.android.resources.ResourceType; - -/** - * Describes a Theme/Style XML attribute displayed by a {@link UiResourceAttributeNode} - * <p/> - * Used by the override for .../theme in {@link AndroidManifestDescriptors}. - */ -public final class ThemeAttributeDescriptor extends TextAttributeDescriptor { - - /** - * Used by {@link DescriptorsUtils} to create instances of this descriptor. - */ - public static final ITextAttributeCreator CREATOR = new ITextAttributeCreator() { - @Override - public TextAttributeDescriptor create(String xmlLocalName, - String nsUri, IAttributeInfo attrInfo) { - return new ThemeAttributeDescriptor(xmlLocalName, nsUri, attrInfo); - } - }; - - public ThemeAttributeDescriptor(String xmlLocalName, String nsUri, IAttributeInfo attrInfo) { - super(xmlLocalName, nsUri, attrInfo); - } - - /** - * @return A new {@link UiResourceAttributeNode} linked to this theme descriptor. - */ - @Override - public UiAttributeNode createUiNode(UiElementNode uiParent) { - return new UiResourceAttributeNode(ResourceType.STYLE, this, uiParent); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java deleted file mode 100644 index 4c829d9ec..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java +++ /dev/null @@ -1,736 +0,0 @@ -/* - * 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.editors.manifest.model; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.xml.AndroidManifest; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.Flags; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeHierarchy; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; -import org.eclipse.jdt.ui.IJavaElementSearchConstants; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.jdt.ui.actions.OpenNewClassWizardAction; -import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension; -import org.eclipse.jdt.ui.dialogs.ITypeInfoRequestor; -import org.eclipse.jdt.ui.dialogs.ITypeSelectionComponent; -import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension; -import org.eclipse.jdt.ui.wizards.NewClassWizardPage; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -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.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.dialogs.SelectionDialog; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.w3c.dom.Element; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * 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. - * <p/> - * See {@link UiTextAttributeNode} for more information. - */ -public class UiClassAttributeNode extends UiTextAttributeNode { - - private String mReferenceClass; - private IPostTypeCreationAction mPostCreationAction; - private boolean mMandatory; - private final boolean mDefaultToProjectOnly; - - private class HierarchyTypeSelection extends TypeSelectionExtension { - - private IJavaProject mJavaProject; - private IType mReferenceType; - private Button mProjectOnly; - private boolean mUseProjectOnly; - - public HierarchyTypeSelection(IProject project, String referenceClass) - throws JavaModelException { - mJavaProject = JavaCore.create(project); - mReferenceType = mJavaProject.findType(referenceClass); - } - - @Override - public ITypeInfoFilterExtension getFilterExtension() { - return new ITypeInfoFilterExtension() { - @Override - public boolean select(ITypeInfoRequestor typeInfoRequestor) { - - boolean projectOnly = mUseProjectOnly; - - String packageName = typeInfoRequestor.getPackageName(); - String typeName = typeInfoRequestor.getTypeName(); - String enclosingType = typeInfoRequestor.getEnclosingName(); - - // build the full class name. - StringBuilder sb = new StringBuilder(packageName); - sb.append('.'); - if (enclosingType.length() > 0) { - sb.append(enclosingType); - sb.append('.'); - } - sb.append(typeName); - - String className = sb.toString(); - - try { - IType type = mJavaProject.findType(className); - - if (type == null) { - return false; - } - - // don't display abstract classes - if ((type.getFlags() & Flags.AccAbstract) != 0) { - return false; - } - - // if project-only is selected, make sure the package fragment is - // an actual source (thus "from this project"). - if (projectOnly) { - IPackageFragment frag = type.getPackageFragment(); - if (frag == null || frag.getKind() != IPackageFragmentRoot.K_SOURCE) { - return false; - } - } - - // get the type hierarchy and reference type is one of the super classes. - ITypeHierarchy hierarchy = type.newSupertypeHierarchy( - new NullProgressMonitor()); - - IType[] supertypes = hierarchy.getAllSupertypes(type); - int n = supertypes.length; - for (int i = 0; i < n; i++) { - IType st = supertypes[i]; - if (mReferenceType.equals(st)) { - return true; - } - } - } catch (JavaModelException e) { - } - - return false; - } - }; - } - - @Override - public Control createContentArea(Composite parent) { - - mProjectOnly = new Button(parent, SWT.CHECK); - mProjectOnly.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mProjectOnly.setText(String.format("Display classes from sources of project '%s' only", - mJavaProject.getProject().getName())); - - mUseProjectOnly = mDefaultToProjectOnly; - mProjectOnly.setSelection(mUseProjectOnly); - - mProjectOnly.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - mUseProjectOnly = mProjectOnly.getSelection(); - getTypeSelectionComponent().triggerSearch(); - } - }); - - return super.createContentArea(parent); - } - } - - /** - * Classes which implement this interface provide a method processing newly created classes. - */ - public static interface IPostTypeCreationAction { - /** - * Sent to process a newly created class. - * @param newType the IType representing the newly created class. - */ - public void processNewType(IType newType); - } - - /** - * Creates a {@link UiClassAttributeNode} object that will display ui to select or create - * classes. - * @param referenceClass The allowed supertype of the classes that are to be selected - * or created. Can be null. - * @param postCreationAction a {@link IPostTypeCreationAction} object handling post creation - * modification of the class. - * @param mandatory indicates if the class value is mandatory - * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node. - * @param defaultToProjectOnly When true display classes of this project only by default. - * When false any class path will be considered. The user can always toggle this. - */ - public UiClassAttributeNode(String referenceClass, IPostTypeCreationAction postCreationAction, - boolean mandatory, AttributeDescriptor attributeDescriptor, UiElementNode uiParent, - boolean defaultToProjectOnly) { - super(attributeDescriptor, uiParent); - - mReferenceClass = referenceClass; - mPostCreationAction = postCreationAction; - mMandatory = mandatory; - mDefaultToProjectOnly = defaultToProjectOnly; - } - - /* (non-java doc) - * Creates a label widget and an associated text field. - * <p/> - * As most other parts of the android manifest editor, this assumes the - * parent uses a table layout with 2 columns. - */ - @Override - public void createUiControl(final Composite parent, 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(); - } - }); - } - - /* (non-java doc) - * - * Add a modify listener that will check the validity of the class - */ - @Override - protected void onAddValidators(final Text text) { - ModifyListener listener = new ModifyListener() { - @Override - 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 = AndroidManifest.combinePackageAndClassName( - javaPackage, textValue); - - // only test the vilibility for activities. - boolean testVisibility = SdkConstants.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() { - @Override - 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 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(AdtConstants.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 IProject getProject() { - UiElementNode uiNode = getUiParent(); - AndroidXmlEditor 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; - } - - - /** - * Returns the current value of the /manifest/package attribute. - * @return the package or an empty string if not found - */ - private String getManifestPackage() { - // 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$ - } - - - /** - * Computes and return the {@link IPackageFragmentRoot}s corresponding to the source folders of - * the specified project. - * @param project the project - * @param include_containers True to include containers - * @return an array of IPackageFragmentRoot. - */ - private IPackageFragmentRoot[] getPackageFragmentRoots(IProject project, - boolean include_containers) { - 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()]); - } - - private void handleNewType(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(AdtConstants.RE_DOT); - if (packages.length == 1) { - text.setText(name); - } else { - text.setText("." + name); //$NON-NLS-1$ - } - } else { - text.setText(name); - } - } - - private void createNewClass(String packageName, 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(); - } - } - } - } - - /** - * Sets the error messages. If message is <code>null</code>, the message is removed. - * @param message the message to set, or <code>null</code> to remove the current message - * @param textWidget the {@link Text} widget associated to the message. - */ - private final void setErrorMessage(String message, Text textWidget) { - if (message != null) { - setHasError(true); - getManagedForm().getMessageManager().addMessage(textWidget, message, null /* data */, - IMessageProvider.ERROR, textWidget); - } else { - setHasError(false); - getManagedForm().getMessageManager().removeMessage(textWidget, textWidget); - } - } - - @Override - public String[] getPossibleValues(String prefix) { - // Compute a list of existing classes for content assist completion - IProject project = getProject(); - if (project == null || mReferenceClass == null) { - return null; - } - - try { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - IType type = javaProject.findType(mReferenceClass); - // Use sets because query sometimes repeats the same class - Set<String> libraryTypes = new HashSet<String>(80); - Set<String> localTypes = new HashSet<String>(30); - if (type != null) { - ITypeHierarchy hierarchy = type.newTypeHierarchy(new NullProgressMonitor()); - IType[] allSubtypes = hierarchy.getAllSubtypes(type); - for (IType subType : allSubtypes) { - int flags = subType.getFlags(); - if (Flags.isPublic(flags) && !Flags.isAbstract(flags)) { - String fqcn = subType.getFullyQualifiedName(); - if (subType.getResource() != null) { - localTypes.add(fqcn); - } else { - libraryTypes.add(fqcn); - } - } - } - } - - List<String> local = new ArrayList<String>(localTypes); - List<String> library = new ArrayList<String>(libraryTypes); - Collections.sort(local); - Collections.sort(library); - List<String> combined = new ArrayList<String>(local.size() + library.size()); - combined.addAll(local); - combined.addAll(library); - return combined.toArray(new String[combined.size()]); - } catch (Exception e) { - AdtPlugin.log(e, null); - } - - return null; - } -} - diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java deleted file mode 100644 index 0151d4d46..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.editors.manifest.model; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.ManifestElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; - -import org.w3c.dom.Element; - -/** - * Represents an XML node that can be modified by the user interface in the XML editor. - * <p/> - * Each tree viewer used in the application page's parts needs to keep a model representing - * each underlying node in the tree. This interface represents the base type for such a node. - * <p/> - * Each node acts as an intermediary model between the actual XML model (the real data support) - * and the tree viewers or the corresponding page parts. - * <p/> - * Element nodes don't contain data per se. Their data is contained in their attributes - * as well as their children's attributes, see {@link UiAttributeNode}. - * <p/> - * The structure of a given {@link UiElementNode} is declared by a corresponding - * {@link ElementDescriptor}. - */ -public final class UiManifestElementNode extends UiElementNode { - - /** - * Creates a new {@link UiElementNode} described by a given {@link ElementDescriptor}. - * - * @param elementDescriptor The {@link ElementDescriptor} for the XML node. Cannot be null. - */ - public UiManifestElementNode(ManifestElementDescriptor elementDescriptor) { - super(elementDescriptor); - } - - /** - * Computes a short string describing the UI node suitable for tree views. - * Uses the element's attribute "android:name" if present, or the "android:label" one - * followed by the element's name if not repeated. - * - * @return A short string describing the UI node suitable for tree views. - */ - @Override - public String getShortDescription() { - AndroidTargetData target = getAndroidTarget(); - AndroidManifestDescriptors manifestDescriptors = null; - if (target != null) { - manifestDescriptors = target.getManifestDescriptors(); - } - - String name = getDescriptor().getUiName(); - - if (manifestDescriptors != null && - getXmlNode() != null && - getXmlNode() instanceof Element && - getXmlNode().hasAttributes()) { - - // Application and Manifest nodes have a special treatment: they are unique nodes - // so we don't bother trying to differentiate their strings and we fall back to - // just using the UI name below. - ElementDescriptor desc = getDescriptor(); - if (desc != manifestDescriptors.getManifestElement() && - desc != manifestDescriptors.getApplicationElement()) { - Element elem = (Element) getXmlNode(); - String attr = _Element_getAttributeNS(elem, - SdkConstants.NS_RESOURCES, - AndroidManifestDescriptors.ANDROID_NAME_ATTR); - if (attr == null || attr.length() == 0) { - attr = _Element_getAttributeNS(elem, - SdkConstants.NS_RESOURCES, - AndroidManifestDescriptors.ANDROID_LABEL_ATTR); - } - if (attr != null && attr.length() > 0) { - // If the ui name is repeated in the attribute value, don't use it. - // Typical case is to avoid ".pkg.MyActivity (Activity)". - if (attr.contains(name)) { - return attr; - } else { - return String.format("%1$s (%2$s)", attr, name); - } - } - } - } - - return String.format("%1$s", name); - } - - /** - * Retrieves an attribute value by local name and namespace URI. - * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] - * , applications must use the value <code>null</code> as the - * <code>namespaceURI</code> parameter for methods if they wish to have - * no namespace. - * <p/> - * Note: This is a wrapper around {@link Element#getAttributeNS(String, String)}. - * In some versions of webtools, the getAttributeNS implementation crashes with an NPE. - * This wrapper will return null instead. - * - * @see Element#getAttributeNS(String, String) - * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318108">https://bugs.eclipse.org/bugs/show_bug.cgi?id=318108</a> - * @return The result from {@link Element#getAttributeNS(String, String)} or or an empty string. - */ - private String _Element_getAttributeNS(Element element, - String namespaceURI, - String localName) { - try { - return element.getAttributeNS(namespaceURI, localName); - } catch (Exception ignore) { - return ""; - } - } -} - diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java deleted file mode 100755 index 60d9125f6..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2009 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.editors.manifest.model; - -import com.android.ide.common.xml.ManifestData; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.ProjectHelper; -import com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction; -import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard; - -import org.eclipse.core.resources.IFile; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -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.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.Composite; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.dialogs.ElementListSelectionDialog; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.eclipse.ui.part.FileEditorInput; - -import java.util.TreeSet; - -/** - * Represents an XML attribute to select an existing manifest package, that can be modified using - * a simple text field or a dialog to choose an existing package. - * <p/> - * See {@link UiTextAttributeNode} for more information. - */ -public class UiManifestPkgAttrNode extends UiTextAttributeNode { - - /** - * Creates a {@link UiManifestPkgAttrNode} object that will display ui to select or create - * a manifest package. - * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node. - */ - public UiManifestPkgAttrNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) { - super(attributeDescriptor, uiParent); - } - - /* (non-java doc) - * Creates a label widget and an associated text field. - * <p/> - * As most other parts of the android manifest editor, this assumes the - * parent uses a table layout with 2 columns. - */ - @Override - public void createUiControl(final Composite parent, final IManagedForm managedForm) { - setManagedForm(managedForm); - FormToolkit toolkit = managedForm.getToolkit(); - TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor(); - - StringBuilder label = new StringBuilder(); - label.append("<form><p><a href='unused'>"); //$NON-NLS-1$ - label.append(desc.getUiName()); - label.append("</a></p></form>"); //$NON-NLS-1$ - 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); - doLabelClick(); - } - }); - 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); - - setTextWidget(text); - - Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH); - - browseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - doBrowseClick(); - } - }); - - } - - /* (non-java doc) - * Adds a validator to the text field that calls managedForm.getMessageManager(). - */ - @Override - protected void onAddValidators(final Text text) { - ModifyListener listener = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - String package_name = text.getText(); - if (package_name.indexOf('.') < 1) { - getManagedForm().getMessageManager().addMessage(text, - "Package name should contain at least two identifiers.", - null /* data */, IMessageProvider.ERROR, text); - } else { - getManagedForm().getMessageManager().removeMessage(text, text); - } - } - }; - - text.addModifyListener(listener); - - // Make sure the validator removes its message(s) when the widget is disposed - text.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - getManagedForm().getMessageManager().removeMessage(text, text); - } - }); - - // Finally call the validator once to make sure the initial value is processed - listener.modifyText(null); - } - - /** - * Handles response to the Browse button by creating a Package dialog. - * */ - private void doBrowseClick() { - - // Display the list of AndroidManifest packages in a selection dialog - ElementListSelectionDialog dialog = new ElementListSelectionDialog( - getTextWidget().getShell(), - new ILabelProvider() { - @Override - public Image getImage(Object element) { - return null; - } - - @Override - public String getText(Object element) { - return element.toString(); - } - - @Override - public void addListener(ILabelProviderListener listener) { - } - - @Override - public void dispose() { - } - - @Override - public boolean isLabelProperty(Object element, String property) { - return false; - } - - @Override - public void removeListener(ILabelProviderListener listener) { - } - }); - - dialog.setTitle("Android Manifest Package Selection"); - dialog.setMessage("Select the Android Manifest package to target."); - - dialog.setElements(getPossibleValues(null)); - - // open the dialog and use the object selected if OK was clicked, or null otherwise - if (dialog.open() == Window.OK) { - String result = (String) dialog.getFirstResult(); - if (result != null && result.length() > 0) { - getTextWidget().setText(result); - } - } - } - - /** - * Handles response to the Label hyper link being activated. - */ - private void doLabelClick() { - // get the current package name - String package_name = getTextWidget().getText().trim(); - - if (package_name.length() == 0) { - createNewProject(); - } else { - displayExistingManifest(package_name); - } - } - - /** - * When the label is clicked and there's already a package name, this method - * attempts to find the project matching the android package name and it attempts - * to open the manifest editor. - * - * @param package_name The android package name to find. Must not be null. - */ - private void displayExistingManifest(String package_name) { - - // Look for the first project that uses this package name - for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) { - // check that there is indeed a manifest file. - IFile manifestFile = ProjectHelper.getManifest(project.getProject()); - if (manifestFile == null) { - // no file? skip this project. - continue; - } - - ManifestData manifestData = AndroidManifestHelper.parseForData(manifestFile); - if (manifestData == null) { - // skip this project. - continue; - } - - if (package_name.equals(manifestData.getPackage())) { - // Found the project. - - IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (win != null) { - IWorkbenchPage page = win.getActivePage(); - if (page != null) { - try { - page.openEditor( - new FileEditorInput(manifestFile), - ManifestEditor.ID, - true, /* activate */ - IWorkbenchPage.MATCH_INPUT); - } catch (PartInitException e) { - AdtPlugin.log(e, - "Opening editor failed for %s", //$NON-NLS-1$ - manifestFile.getFullPath()); - } - } - } - - // We found the project; even if we failed there's no need to keep looking. - return; - } - } - } - - /** - * Displays the New Project Wizard to create a new project. - * If one is successfully created, use the Android Package name. - */ - private void createNewProject() { - - NewProjectAction npwAction = new NewProjectAction(); - npwAction.run(null /*action*/); - if (npwAction.getDialogResult() == Dialog.OK) { - NewProjectWizard npw = (NewProjectWizard) npwAction.getWizard(); - String name = npw.getPackageName(); - if (name != null && name.length() > 0) { - getTextWidget().setText(name); - } - } - } - - /** - * Returns all the possible android package names that could be used. - * The prefix is not used. - * - * {@inheritDoc} - */ - @Override - public String[] getPossibleValues(String prefix) { - TreeSet<String> packages = new TreeSet<String>(); - - for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) { - // check that there is indeed a manifest file. - ManifestData manifestData = AndroidManifestHelper.parseForData(project.getProject()); - if (manifestData == null) { - // skip this project. - continue; - } - - packages.add(manifestData.getPackage()); - } - - return packages.toArray(new String[packages.size()]); - } -} - diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java deleted file mode 100644 index e6a2007b3..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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.editors.manifest.model; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.jdt.ui.actions.OpenNewPackageWizardAction; -import org.eclipse.jdt.ui.actions.ShowInPackageViewAction; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -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.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.dialogs.SelectionDialog; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.TableWrapData; - -import java.util.ArrayList; - -/** - * Represents an XML attribute for a package, that can be modified using a simple text field or - * a dialog to choose an existing package. Also, there's a link to create a new package. - * <p/> - * See {@link UiTextAttributeNode} for more information. - */ -public class UiPackageAttributeNode extends UiTextAttributeNode { - - /** - * Creates a {@link UiPackageAttributeNode} object that will display ui to select or create - * a package. - * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node. - */ - public UiPackageAttributeNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) { - super(attributeDescriptor, uiParent); - } - - /* (non-java doc) - * Creates a label widget and an associated text field. - * <p/> - * As most other parts of the android manifest editor, this assumes the - * parent uses a table layout with 2 columns. - */ - @Override - public void createUiControl(final Composite parent, final IManagedForm managedForm) { - setManagedForm(managedForm); - FormToolkit toolkit = managedForm.getToolkit(); - TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor(); - - StringBuilder label = new StringBuilder(); - label.append("<form><p><a href='unused'>"); //$NON-NLS-1$ - label.append(desc.getUiName()); - label.append("</a></p></form>"); //$NON-NLS-1$ - 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); - doLabelClick(); - } - }); - 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); - - setTextWidget(text); - - Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH); - - browseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - doBrowseClick(); - } - }); - - } - - /* (non-java doc) - * Adds a validator to the text field that calls managedForm.getMessageManager(). - */ - @Override - protected void onAddValidators(final Text text) { - ModifyListener listener = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - String package_name = text.getText(); - if (package_name.indexOf('.') < 1) { - getManagedForm().getMessageManager().addMessage(text, - "Package name should contain at least two identifiers.", - null /* data */, IMessageProvider.ERROR, text); - } else { - getManagedForm().getMessageManager().removeMessage(text, text); - } - } - }; - - text.addModifyListener(listener); - - // Make sure the validator removes its message(s) when the widget is disposed - text.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - getManagedForm().getMessageManager().removeMessage(text, text); - } - }); - - // Finally call the validator once to make sure the initial value is processed - listener.modifyText(null); - } - - /** - * Handles response to the Browse button by creating a Package dialog. - * */ - private void doBrowseClick() { - Text text = getTextWidget(); - - // we need to get the project of the manifest. - IProject project = getProject(); - if (project != null) { - - try { - SelectionDialog dlg = JavaUI.createPackageDialog(text.getShell(), - JavaCore.create(project), 0); - dlg.setTitle("Select Android Package"); - dlg.setMessage("Select the package for the Android project."); - SelectionDialog.setDefaultImage(AdtPlugin.getAndroidLogo()); - - if (dlg.open() == Window.OK) { - Object[] results = dlg.getResult(); - if (results.length == 1) { - setPackageTextField((IPackageFragment)results[0]); - } - } - } catch (JavaModelException e1) { - } - } - } - - /** - * Handles response to the Label hyper link being activated. - */ - private void doLabelClick() { - // get the current package name - String package_name = getTextWidget().getText().trim(); - - if (package_name.length() == 0) { - createNewPackage(); - } else { - // Try to select the package in the Package Explorer for the current - // project and the current editor's site. - - IProject project = getProject(); - if (project == null) { - AdtPlugin.log(IStatus.ERROR, "Failed to get project for UiPackageAttribute"); //$NON-NLS-1$ - return; - } - - IWorkbenchPartSite site = getUiParent().getEditor().getSite(); - if (site == null) { - AdtPlugin.log(IStatus.ERROR, "Failed to get editor site for UiPackageAttribute"); //$NON-NLS-1$ - return; - } - - for (IPackageFragmentRoot root : getPackageFragmentRoots(project)) { - IPackageFragment fragment = root.getPackageFragment(package_name); - if (fragment != null && fragment.exists()) { - ShowInPackageViewAction action = new ShowInPackageViewAction(site); - action.run(fragment); - // This action's run() doesn't provide the status (although internally it could) - // so we just assume it worked. - return; - } - } - } - } - - /** - * Utility method that returns the project for the current file being edited. - * - * @return The IProject for the current file being edited or null. - */ - private IProject getProject() { - UiElementNode uiNode = getUiParent(); - AndroidXmlEditor 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; - } - - /** - * Utility method that computes and returns the list of {@link IPackageFragmentRoot} - * corresponding to the source folder of the specified project. - * - * @param project the project - * @return an array of IPackageFragmentRoot. Can be empty but not null. - */ - private IPackageFragmentRoot[] getPackageFragmentRoots(IProject 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) { - result.add(roots[i]); - } - } - } catch (JavaModelException e) { - } - - return result.toArray(new IPackageFragmentRoot[result.size()]); - } - - /** - * Utility method that sets the package's text field to the package fragment's name. - * */ - private void setPackageTextField(IPackageFragment type) { - Text text = getTextWidget(); - - String name = type.getElementName(); - - text.setText(name); - } - - - /** - * Displays and handles a "Create Package Wizard". - * - * This is invoked by doLabelClick() when clicking on the hyperlink label with an - * empty package text field. - */ - private void createNewPackage() { - OpenNewPackageWizardAction action = new OpenNewPackageWizardAction(); - - IProject project = getProject(); - action.setSelection(new StructuredSelection(project)); - action.run(); - - IJavaElement element = action.getCreatedElement(); - if (element != null && - element.exists() && - element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { - setPackageTextField((IPackageFragment) element); - } - } - - @Override - public String[] getPossibleValues(String prefix) { - // TODO: compute a list of existing packages for content assist completion - return null; - } -} - diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java deleted file mode 100644 index 7d3f6a89f..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart; -import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; - -/** - * Application's attributes section part for Application page. - * <p/> - * This part is displayed at the top of the application page and displays all the possible - * attributes of an application node in the AndroidManifest (icon, class name, label, etc.) - */ -final class ApplicationAttributesPart extends UiElementPart { - - /** Listen to changes to the UI node for <application> and updates the UI */ - private AppNodeUpdateListener mAppNodeUpdateListener; - /** ManagedForm needed to create the UI controls */ - private IManagedForm mManagedForm; - - public ApplicationAttributesPart(Composite body, FormToolkit toolkit, ManifestEditor editor, - UiElementNode applicationUiNode) { - super(body, toolkit, editor, applicationUiNode, - "Application Attributes", // section title - "Defines the attributes specific to the application.", // section description - Section.TWISTIE | Section.EXPANDED); - } - - /** - * Changes and refreshes the Application UI node handle by the this part. - */ - @Override - public void setUiElementNode(UiElementNode uiElementNode) { - super.setUiElementNode(uiElementNode); - - createUiAttributes(mManagedForm); - } - - /* (non-java doc) - * Create the controls to edit the attributes for the given ElementDescriptor. - * <p/> - * This MUST not be called by the constructor. Instead it must be called from - * <code>initialize</code> (i.e. right after the form part is added to the managed form.) - * <p/> - * Derived classes can override this if necessary. - * - * @param managedForm The owner managed form - */ - @Override - protected void createFormControls(final IManagedForm managedForm) { - mManagedForm = managedForm; - setTable(createTableLayout(managedForm.getToolkit(), 4 /* numColumns */)); - - mAppNodeUpdateListener = new AppNodeUpdateListener(); - getUiElementNode().addUpdateListener(mAppNodeUpdateListener); - - createUiAttributes(mManagedForm); - } - - @Override - public void dispose() { - super.dispose(); - if (getUiElementNode() != null && mAppNodeUpdateListener != null) { - getUiElementNode().removeUpdateListener(mAppNodeUpdateListener); - mAppNodeUpdateListener = null; - } - } - - @Override - protected void createUiAttributes(IManagedForm managedForm) { - Composite table = getTable(); - if (table == null || managedForm == null) { - return; - } - - // Remove any old UI controls - for (Control c : table.getChildren()) { - c.dispose(); - } - - UiElementNode uiElementNode = getUiElementNode(); - AttributeDescriptor[] attr_desc_list = uiElementNode.getAttributeDescriptors(); - - // Display the attributes in 2 columns: - // attr 0 | attr 4 - // attr 1 | attr 5 - // attr 2 | attr 6 - // attr 3 | attr 7 - // that is we have to fill the grid in order 0, 4, 1, 5, 2, 6, 3, 7 - // thus index = i/2 + (i is odd * n/2) - int n = attr_desc_list.length; - int n2 = (int) Math.ceil(n / 2.0); - for (int i = 0; i < n; i++) { - AttributeDescriptor attr_desc = attr_desc_list[i / 2 + (i & 1) * n2]; - if (attr_desc instanceof XmlnsAttributeDescriptor) { - // Do not show hidden attributes - continue; - } - - UiAttributeNode ui_attr = uiElementNode.findUiAttribute(attr_desc); - if (ui_attr != null) { - ui_attr.createUiControl(table, managedForm); - } else { - // The XML has an extra attribute which wasn't declared in - // AndroidManifestDescriptors. This is not a problem, we just ignore it. - AdtPlugin.log(IStatus.WARNING, - "Attribute %1$s not declared in node %2$s, ignored.", //$NON-NLS-1$ - attr_desc.getXmlLocalName(), - uiElementNode.getDescriptor().getXmlName()); - } - } - - if (n == 0) { - createLabel(table, managedForm.getToolkit(), - "No attributes to display, waiting for SDK to finish loading...", - null /* tooltip */ ); - } - - // Initialize the enabled/disabled state - if (mAppNodeUpdateListener != null) { - mAppNodeUpdateListener.uiElementNodeUpdated(uiElementNode, null /* state, not used */); - } - - // Tell the section that the layout has changed. - layoutChanged(); - } - - /** - * This listener synchronizes the UI with the actual presence of the application XML node. - */ - private class AppNodeUpdateListener implements IUiUpdateListener { - @Override - public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) { - // The UiElementNode for the application XML node always exists, even - // if there is no corresponding XML node in the XML file. - // - // We enable the UI here if the XML node is not null. - Composite table = getTable(); - boolean exists = (ui_node.getXmlNode() != null); - if (table != null && table.getEnabled() != exists) { - table.setEnabled(exists); - for (Control c : table.getChildren()) { - c.setEnabled(exists); - } - } - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java deleted file mode 100644 index 06a3d3f3e..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IPageImageProvider; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; - - -/** - * Page for "Application" settings, part of the AndroidManifest form editor. - * <p/> - * Useful reference: - * <a href="http://www.eclipse.org/articles/Article-Forms/article.html"> - * http://www.eclipse.org/articles/Article-Forms/article.html</a> - */ -public final class ApplicationPage extends FormPage implements IPageImageProvider { - /** Page id used for switching tabs programmatically */ - public final static String PAGE_ID = "application_page"; //$NON-NLS-1$ - - /** Container editor */ - ManifestEditor mEditor; - /** The Application Toogle part */ - private ApplicationToggle mTooglePart; - /** The Application Attributes part */ - private ApplicationAttributesPart mAttrPart; - /** The tree view block */ - private UiTreeBlock mTreeBlock; - - public ApplicationPage(ManifestEditor editor) { - super(editor, PAGE_ID, "Application"); // tab's label, keep it short - mEditor = editor; - } - - @Override - public Image getPageImage() { - return IconFactory.getInstance().getIcon(getTitle(), - IconFactory.COLOR_BLUE, - IconFactory.SHAPE_RECT); - } - - /** - * Creates the content in the form hosted in this page. - * - * @param managedForm the form hosted in this page. - */ - @Override - protected void createFormContent(IManagedForm managedForm) { - super.createFormContent(managedForm); - ScrolledForm form = managedForm.getForm(); - form.setText("Android Manifest Application"); - form.setImage(AdtPlugin.getAndroidLogo()); - - UiElementNode appUiNode = getUiApplicationNode(); - - Composite body = form.getBody(); - FormToolkit toolkit = managedForm.getToolkit(); - - // We usually prefer to have a ColumnLayout here. However - // MasterDetailsBlock.createContent() below will reset the body's layout to a grid layout. - mTooglePart = new ApplicationToggle(body, toolkit, mEditor, appUiNode); - mTooglePart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - managedForm.addPart(mTooglePart); - mAttrPart = new ApplicationAttributesPart(body, toolkit, mEditor, appUiNode); - mAttrPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - managedForm.addPart(mAttrPart); - - mTreeBlock = new UiTreeBlock(mEditor, appUiNode, - false /* autoCreateRoot */, - null /* element filters */, - "Application Nodes", - "List of all elements in the application"); - mTreeBlock.createContent(managedForm); - } - - /** - * Retrieves the application UI node. Since this is a mandatory node, it *always* - * exists, even if there is no matching XML node. - */ - private UiElementNode getUiApplicationNode() { - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - if (manifestDescriptor != null) { - ElementDescriptor desc = manifestDescriptor.getApplicationElement(); - return mEditor.getUiRootNode().findUiChildNode(desc.getXmlName()); - } else { - // return the ui root node, as a dummy application root node. - return mEditor.getUiRootNode(); - } - } - - /** - * Changes and refreshes the Application UI node handled by the sub parts. - */ - public void refreshUiApplicationNode() { - UiElementNode appUiNode = getUiApplicationNode(); - if (mTooglePart != null) { - mTooglePart.setUiElementNode(appUiNode); - } - if (mAttrPart != null) { - mAttrPart.setUiElementNode(appUiNode); - } - if (mTreeBlock != null) { - mTreeBlock.changeRootAndDescriptors(appUiNode, - null /* element filters */, - true /* refresh */); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java deleted file mode 100644 index 159f08959..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart; -import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener; -import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener.UiUpdateState; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.utils.SdkUtils; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.forms.widgets.TableWrapData; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.Text; - -/** - * Appllication Toogle section part for application page. - */ -final class ApplicationToggle extends UiElementPart { - - /** Checkbox indicating whether an application node is present */ - private Button mCheckbox; - /** Listen to changes to the UI node for <application> and updates the checkbox */ - private AppNodeUpdateListener mAppNodeUpdateListener; - /** Internal flag to know where we're programmatically modifying the checkbox and we want to - * avoid triggering the checkbox's callback. */ - public boolean mInternalModification; - private FormText mTooltipFormText; - - public ApplicationToggle(Composite body, FormToolkit toolkit, ManifestEditor editor, - UiElementNode applicationUiNode) { - super(body, toolkit, editor, applicationUiNode, - "Application Toggle", - null, /* description */ - Section.TWISTIE | Section.EXPANDED); - } - - @Override - public void dispose() { - super.dispose(); - if (getUiElementNode() != null && mAppNodeUpdateListener != null) { - getUiElementNode().removeUpdateListener(mAppNodeUpdateListener); - mAppNodeUpdateListener = null; - } - } - - /** - * Changes and refreshes the Application UI node handle by the this part. - */ - @Override - public void setUiElementNode(UiElementNode uiElementNode) { - super.setUiElementNode(uiElementNode); - - updateTooltip(); - - // Set the state of the checkbox - mAppNodeUpdateListener.uiElementNodeUpdated(getUiElementNode(), - UiUpdateState.CHILDREN_CHANGED); - } - - /** - * Create the controls to edit the attributes for the given ElementDescriptor. - * <p/> - * This MUST not be called by the constructor. Instead it must be called from - * <code>initialize</code> (i.e. right after the form part is added to the managed form.) - * - * @param managedForm The owner managed form - */ - @Override - protected void createFormControls(IManagedForm managedForm) { - FormToolkit toolkit = managedForm.getToolkit(); - Composite table = createTableLayout(toolkit, 1 /* numColumns */); - - mTooltipFormText = createFormText(table, toolkit, true, "<form></form>", - false /* setupLayoutData */); - updateTooltip(); - - mCheckbox = toolkit.createButton(table, - "Define an <application> tag in the AndroidManifest.xml", - SWT.CHECK); - mCheckbox.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP)); - mCheckbox.setSelection(false); - mCheckbox.addSelectionListener(new CheckboxSelectionListener()); - - mAppNodeUpdateListener = new AppNodeUpdateListener(); - getUiElementNode().addUpdateListener(mAppNodeUpdateListener); - - // Initialize the state of the checkbox - mAppNodeUpdateListener.uiElementNodeUpdated(getUiElementNode(), - UiUpdateState.CHILDREN_CHANGED); - - // Tell the section that the layout has changed. - layoutChanged(); - } - - /** - * Updates the application tooltip in the form text. - * If there is no tooltip, the form text is hidden. - */ - private void updateTooltip() { - boolean isVisible = false; - - String tooltip = getUiElementNode().getDescriptor().getTooltip(); - if (tooltip != null) { - tooltip = DescriptorsUtils.formatFormText(tooltip, - getUiElementNode().getDescriptor(), - Sdk.getCurrent().getDocumentationBaseUrl()); - - mTooltipFormText.setText(tooltip, true /* parseTags */, true /* expandURLs */); - mTooltipFormText.setImage(DescriptorsUtils.IMAGE_KEY, AdtPlugin.getAndroidLogo()); - mTooltipFormText.addHyperlinkListener(getEditor().createHyperlinkListener()); - isVisible = true; - } - - mTooltipFormText.setVisible(isVisible); - } - - /** - * This listener synchronizes the XML application node when the checkbox - * is changed by the user. - */ - private class CheckboxSelectionListener extends SelectionAdapter { - private Node mUndoXmlNode; - private Node mUndoXmlParent; - private Node mUndoXmlNextNode; - private Node mUndoXmlNextElement; - private Document mUndoXmlDocument; - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - if (!mInternalModification && getUiElementNode() != null) { - getUiElementNode().getEditor().wrapUndoEditXmlModel( - mCheckbox.getSelection() - ? "Create or restore Application node" - : "Remove Application node", - new Runnable() { - @Override - public void run() { - if (mCheckbox.getSelection()) { - // The user wants an <application> node. - // Either restore a previous one - // or create a full new one. - boolean create = true; - if (mUndoXmlNode != null) { - create = !restoreApplicationNode(); - } - if (create) { - getUiElementNode().createXmlNode(); - } - } else { - // Users no longer wants the <application> node. - removeApplicationNode(); - } - } - }); - } - } - - /** - * Restore a previously "saved" application node. - * - * @return True if the node could be restored, false otherwise. - */ - private boolean restoreApplicationNode() { - if (mUndoXmlDocument == null || mUndoXmlNode == null) { - return false; - } - - // Validate node references... - mUndoXmlParent = validateNode(mUndoXmlDocument, mUndoXmlParent); - mUndoXmlNextNode = validateNode(mUndoXmlDocument, mUndoXmlNextNode); - mUndoXmlNextElement = validateNode(mUndoXmlDocument, mUndoXmlNextElement); - - if (mUndoXmlParent == null){ - // If the parent node doesn't exist, try to find a new manifest node. - // If it doesn't exist, create it. - mUndoXmlParent = getUiElementNode().getUiParent().prepareCommit(); - mUndoXmlNextNode = null; - mUndoXmlNextElement = null; - } - - boolean success = false; - if (mUndoXmlParent != null) { - // If the parent is still around, reuse the same node. - - // Ideally we want to insert the node before what used to be its next sibling. - // If that's not possible, we try to insert it before its next sibling element. - // If that's not possible either, it will be inserted at the end of the parent's. - Node next = mUndoXmlNextNode; - if (next == null) { - next = mUndoXmlNextElement; - } - mUndoXmlParent.insertBefore(mUndoXmlNode, next); - if (next == null) { - Text sep = mUndoXmlDocument.createTextNode(SdkUtils.getLineSeparator()); - mUndoXmlParent.insertBefore(sep, null); // insert separator before end tag - } - success = true; - } - - // Remove internal references to avoid using them twice - mUndoXmlParent = null; - mUndoXmlNextNode = null; - mUndoXmlNextElement = null; - mUndoXmlNode = null; - mUndoXmlDocument = null; - return success; - } - - /** - * Validates that the given xml_node is still either the root node or one of its - * direct descendants. - * - * @param root_node The root of the node hierarchy to examine. - * @param xml_node The XML node to find. - * @return Returns xml_node if it is, otherwise returns null. - */ - private Node validateNode(Node root_node, Node xml_node) { - if (root_node == xml_node) { - return xml_node; - } else { - for (Node node = root_node.getFirstChild(); node != null; - node = node.getNextSibling()) { - if (root_node == xml_node || validateNode(node, xml_node) != null) { - return xml_node; - } - } - } - return null; - } - - /** - * Removes the <application> node from the hierarchy. - * Before doing that, we try to remember where it was so that we can put it back - * in the same place. - */ - private void removeApplicationNode() { - // Make sure the node actually exists... - Node xml_node = getUiElementNode().getXmlNode(); - if (xml_node == null) { - return; - } - - // Save its parent, next sibling and next element - mUndoXmlDocument = xml_node.getOwnerDocument(); - mUndoXmlParent = xml_node.getParentNode(); - mUndoXmlNextNode = xml_node.getNextSibling(); - mUndoXmlNextElement = mUndoXmlNextNode; - while (mUndoXmlNextElement != null && - mUndoXmlNextElement.getNodeType() != Node.ELEMENT_NODE) { - mUndoXmlNextElement = mUndoXmlNextElement.getNextSibling(); - } - - // Actually remove the node from the hierarchy and keep it here. - // The returned node looses its parents/siblings pointers. - mUndoXmlNode = getUiElementNode().deleteXmlNode(); - } - } - - /** - * This listener synchronizes the UI (i.e. the checkbox) with the - * actual presence of the application XML node. - */ - private class AppNodeUpdateListener implements IUiUpdateListener { - @Override - public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) { - // The UiElementNode for the application XML node always exists, even - // if there is no corresponding XML node in the XML file. - // - // To update the checkbox to reflect the actual state, we just need - // to check if the XML node is null. - try { - mInternalModification = true; - boolean exists = ui_node.getXmlNode() != null; - if (mCheckbox.getSelection() != exists) { - mCheckbox.setSelection(exists); - } - } finally { - mInternalModification = false; - } - - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java deleted file mode 100644 index a8bb34691..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IPageImageProvider; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Page for instrumentation settings, part of the AndroidManifest form editor. - */ -public final class InstrumentationPage extends FormPage implements IPageImageProvider { - /** Page id used for switching tabs programmatically */ - public final static String PAGE_ID = "instrumentation_page"; //$NON-NLS-1$ - - /** Container editor */ - ManifestEditor mEditor; - - private UiTreeBlock mTreeBlock; - - public InstrumentationPage(ManifestEditor editor) { - super(editor, PAGE_ID, "Instrumentation"); // tab's label, keep it short - mEditor = editor; - } - - @Override - public Image getPageImage() { - return IconFactory.getInstance().getIcon(getTitle(), - IconFactory.COLOR_GREEN, - IconFactory.SHAPE_RECT); - } - - /** - * Creates the content in the form hosted in this page. - * - * @param managedForm the form hosted in this page. - */ - @Override - protected void createFormContent(IManagedForm managedForm) { - super.createFormContent(managedForm); - ScrolledForm form = managedForm.getForm(); - form.setText("Android Manifest Instrumentation"); - form.setImage(AdtPlugin.getAndroidLogo()); - - UiElementNode manifest = mEditor.getUiRootNode(); - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - - ElementDescriptor[] descriptorFilters = null; - if (manifestDescriptor != null) { - descriptorFilters = new ElementDescriptor[] { - manifestDescriptor.getInstrumentationElement(), - }; - } - - mTreeBlock = new UiTreeBlock(mEditor, manifest, - true /* autoCreateRoot */, - descriptorFilters, - "Instrumentation", - "List of instrumentations defined in the manifest"); - mTreeBlock.createContent(managedForm); - } - - /** - * Changes and refreshes the Application UI node handled by the sub parts. - */ - public void refreshUiNode() { - if (mTreeBlock != null) { - UiElementNode manifest = mEditor.getUiRootNode(); - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - - mTreeBlock.changeRootAndDescriptors(manifest, - new ElementDescriptor[] { - manifestDescriptor.getInstrumentationElement() - }, - true /* refresh */); - } - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java deleted file mode 100644 index b0eb75a2d..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart; -import com.android.ide.eclipse.adt.internal.project.ExportHelper; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.events.HyperlinkAdapter; -import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; -import org.eclipse.ui.part.FileEditorInput; - -/** - * Export section part for overview page. - */ -final class OverviewExportPart extends ManifestSectionPart { - - private final OverviewPage mOverviewPage; - - public OverviewExportPart(OverviewPage overviewPage, final Composite body, FormToolkit toolkit, - ManifestEditor editor) { - super(body, toolkit, Section.TWISTIE | Section.EXPANDED, true /* description */); - mOverviewPage = overviewPage; - Section section = getSection(); - section.setText("Exporting"); - - final IProject project = getProject(); - boolean isLibrary = false; - if (project != null) { - ProjectState state = Sdk.getProjectState(project); - if (state != null) { - isLibrary = state.isLibrary(); - } - } - - if (isLibrary) { - section.setDescription("Library project cannot be exported."); - Composite table = createTableLayout(toolkit, 2 /* numColumns */); - createFormText(table, toolkit, true, "<form></form>", false /* setupLayoutData */); - } else { - section.setDescription("To export the application for distribution, you have the following options:"); - - Composite table = createTableLayout(toolkit, 2 /* numColumns */); - - StringBuffer buf = new StringBuffer(); - buf.append("<form><li><a href=\"wizard\">"); //$NON-NLS-1$ - buf.append("Use the Export Wizard"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(" to export and sign an APK"); - buf.append("</li>"); //$NON-NLS-1$ - buf.append("<li><a href=\"manual\">"); //$NON-NLS-1$ - buf.append("Export an unsigned APK"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(" and sign it manually"); - buf.append("</li></form>"); //$NON-NLS-1$ - - FormText text = createFormText(table, toolkit, true, buf.toString(), - false /* setupLayoutData */); - text.addHyperlinkListener(new HyperlinkAdapter() { - @Override - public void linkActivated(HyperlinkEvent e) { - if (project != null) { - if ("manual".equals(e.data)) { //$NON-NLS-1$ - // now we can export an unsigned apk for the project. - ExportHelper.exportUnsignedReleaseApk(project); - } else { - // call the export wizard - StructuredSelection selection = new StructuredSelection(project); - - ExportWizard wizard = new ExportWizard(); - wizard.init(PlatformUI.getWorkbench(), selection); - WizardDialog dialog = new WizardDialog(body.getShell(), wizard); - dialog.open(); - } - } - } - }); - } - - layoutChanged(); - } - - /** - * Returns the project of the edited file. - */ - private IProject getProject() { - IEditorInput input = mOverviewPage.mEditor.getEditorInput(); - if (input instanceof FileEditorInput) { - FileEditorInput fileInput = (FileEditorInput)input; - IFile file = fileInput.getFile(); - return file.getProject(); - } - - return null; - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java deleted file mode 100644 index 98f2f9cc2..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.UiElementPart; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; - -/** - * Generic info section part for overview page: it displays all the attributes from - * the manifest element. - */ -final class OverviewInfoPart extends UiElementPart { - - private IManagedForm mManagedForm; - - public OverviewInfoPart(Composite body, FormToolkit toolkit, ManifestEditor editor) { - super(body, toolkit, editor, - getManifestUiNode(editor), // uiElementNode - "Manifest General Attributes", // section title - "Defines general information about the AndroidManifest.xml", // section description - Section.TWISTIE | Section.EXPANDED); - } - - /** - * Retrieves the UiElementNode that this part will edit. The node must exist - * and can't be null, by design, because it's a mandatory node. - */ - private static UiElementNode getManifestUiNode(ManifestEditor editor) { - AndroidManifestDescriptors manifestDescriptors = editor.getManifestDescriptors(); - if (manifestDescriptors != null) { - ElementDescriptor desc = manifestDescriptors.getManifestElement(); - if (editor.getUiRootNode().getDescriptor() == desc) { - return editor.getUiRootNode(); - } else { - return editor.getUiRootNode().findUiChildNode(desc.getXmlName()); - } - } - - // No manifest descriptor: we have a dummy UiRootNode, so we return that. - // The editor will be reloaded once we have the proper descriptors anyway. - return editor.getUiRootNode(); - } - - /** - * Overridden in order to capture the current managed form. - * - * {@inheritDoc} - */ - @Override - protected void createFormControls(final IManagedForm managedForm) { - mManagedForm = managedForm; - super.createFormControls(managedForm); - } - - /** - * Removes any existing Attribute UI widgets and recreate them if the SDK has changed. - * <p/> - * This is called by {@link OverviewPage#refreshUiApplicationNode()} when the - * SDK has changed. - */ - public void onSdkChanged() { - setUiElementNode(getManifestUiNode(getEditor())); - createUiAttributes(mManagedForm); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java deleted file mode 100644 index f8213753a..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.forms.widgets.FormText; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; - -/** - * Links section part for overview page. - */ -final class OverviewLinksPart extends ManifestSectionPart { - - private final ManifestEditor mEditor; - private FormText mFormText; - - public OverviewLinksPart(Composite body, FormToolkit toolkit, ManifestEditor editor) { - super(body, toolkit, Section.TWISTIE | Section.EXPANDED, true /* description */); - mEditor = editor; - Section section = getSection(); - section.setText("Links"); - section.setDescription("The content of the Android Manifest is made up of three sections. You can also edit the XML directly."); - - Composite table = createTableLayout(toolkit, 2 /* numColumns */); - - StringBuffer buf = new StringBuffer(); - buf.append(String.format("<form><li style=\"image\" value=\"app_img\"><a href=\"page:%1$s\">", //$NON-NLS-1$ - ApplicationPage.PAGE_ID)); - buf.append("Application"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(": Activities, intent filters, providers, services and receivers."); - buf.append("</li>"); //$NON-NLS-1$ - - buf.append(String.format("<li style=\"image\" value=\"perm_img\"><a href=\"page:%1$s\">", //$NON-NLS-1$ - PermissionPage.PAGE_ID)); - buf.append("Permission"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(": Permissions defined and permissions used."); - buf.append("</li>"); //$NON-NLS-1$ - - buf.append(String.format("<li style=\"image\" value=\"inst_img\"><a href=\"page:%1$s\">", //$NON-NLS-1$ - InstrumentationPage.PAGE_ID)); - buf.append("Instrumentation"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(": Instrumentation defined."); - buf.append("</li>"); //$NON-NLS-1$ - - buf.append(String.format("<li style=\"image\" value=\"srce_img\"><a href=\"page:%1$s\">", //$NON-NLS-1$ - ManifestEditor.TEXT_EDITOR_ID)); - buf.append("XML Source"); - buf.append("</a>"); //$NON-NLS-1$ - buf.append(": Directly edit the AndroidManifest.xml file."); - buf.append("</li>"); //$NON-NLS-1$ - - buf.append("<li style=\"image\" value=\"android_img\">"); //$NON-NLS-1$ - buf.append("<a href=\"http://code.google.com/android/devel/bblocks-manifest.html\">Documentation</a>: Documentation from the Android SDK for AndroidManifest.xml."); //$NON-NLS-1$ - buf.append("</li>"); //$NON-NLS-1$ - buf.append("</form>"); //$NON-NLS-1$ - - mFormText = createFormText(table, toolkit, true, buf.toString(), - false /* setupLayoutData */); - - AndroidManifestDescriptors manifestDescriptor = editor.getManifestDescriptors(); - - Image androidLogo = AdtPlugin.getAndroidLogo(); - mFormText.setImage("android_img", androidLogo); //$NON-NLS-1$ - mFormText.setImage("srce_img", IconFactory.getInstance().getIcon(AndroidXmlEditor.ICON_XML_PAGE)); - - if (manifestDescriptor != null) { - mFormText.setImage("app_img", getIcon(manifestDescriptor.getApplicationElement())); //$NON-NLS-1$ - mFormText.setImage("perm_img", getIcon(manifestDescriptor.getPermissionElement())); //$NON-NLS-1$ - mFormText.setImage("inst_img", getIcon(manifestDescriptor.getInstrumentationElement())); //$NON-NLS-1$ - } else { - mFormText.setImage("app_img", androidLogo); //$NON-NLS-1$ - mFormText.setImage("perm_img", androidLogo); //$NON-NLS-1$ - mFormText.setImage("inst_img", androidLogo); //$NON-NLS-1$ - } - mFormText.addHyperlinkListener(editor.createHyperlinkListener()); - } - - /** - * Update the UI with information from the new descriptors. - * <p/>At this point, this only refreshes the icons. - * <p/> - * This is called by {@link OverviewPage#refreshUiApplicationNode()} when the - * SDK has changed. - */ - public void onSdkChanged() { - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - if (manifestDescriptor != null) { - mFormText.setImage("app_img", getIcon(manifestDescriptor.getApplicationElement())); //$NON-NLS-1$ - mFormText.setImage("perm_img", getIcon(manifestDescriptor.getPermissionElement())); //$NON-NLS-1$ - mFormText.setImage("inst_img", getIcon(manifestDescriptor.getInstrumentationElement())); //$NON-NLS-1$ - } - } - - private Image getIcon(ElementDescriptor desc) { - return desc.getCustomizedIcon(); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java deleted file mode 100644 index 7464f6a5f..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IPageImageProvider; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -import java.util.ArrayList; -import java.util.HashSet; - - -/** - * Page for overview settings, part of the AndroidManifest form editor. - * <p/> - * Useful reference: - * <a href="http://www.eclipse.org/articles/Article-Forms/article.html"> - * http://www.eclipse.org/articles/Article-Forms/article.html</a> - */ -public final class OverviewPage extends FormPage implements IPageImageProvider { - - /** Page id used for switching tabs programmatically */ - final static String PAGE_ID = "overview_page"; //$NON-NLS-1$ - - /** Container editor */ - ManifestEditor mEditor; - /** Overview part (attributes for manifest) */ - private OverviewInfoPart mOverviewPart; - /** Overview link part */ - private OverviewLinksPart mOverviewLinkPart; - - private UiTreeBlock mTreeBlock; - - public OverviewPage(ManifestEditor editor) { - super(editor, PAGE_ID, "Manifest"); // tab's label, user visible, keep it short - mEditor = editor; - } - - @Override - public Image getPageImage() { - return IconFactory.getInstance().getIcon("editor_page_design"); //$NON-NLS-1$ - } - - /** - * Creates the content in the form hosted in this page. - * - * @param managedForm the form hosted in this page. - */ - @Override - protected void createFormContent(IManagedForm managedForm) { - super.createFormContent(managedForm); - ScrolledForm form = managedForm.getForm(); - form.setText("Android Manifest"); - form.setImage(AdtPlugin.getAndroidLogo()); - - Composite body = form.getBody(); - FormToolkit toolkit = managedForm.getToolkit(); - - // Usually we would set a ColumnLayout on body here. However the presence of the - // UiTreeBlock forces a GridLayout with one column so we comply with it. - - mOverviewPart = new OverviewInfoPart(body, toolkit, mEditor); - mOverviewPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - managedForm.addPart(mOverviewPart); - - newManifestExtrasPart(managedForm); - - OverviewExportPart exportPart = new OverviewExportPart(this, body, toolkit, mEditor); - exportPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - managedForm.addPart(exportPart); - - mOverviewLinkPart = new OverviewLinksPart(body, toolkit, mEditor); - mOverviewLinkPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - managedForm.addPart(mOverviewLinkPart); - } - - private void newManifestExtrasPart(IManagedForm managedForm) { - UiElementNode manifest = mEditor.getUiRootNode(); - mTreeBlock = new UiTreeBlock(mEditor, manifest, - true /* autoCreateRoot */, - computeManifestExtraFilters(), - "Manifest Extras", - "Extra manifest elements"); - mTreeBlock.createContent(managedForm); - } - - /** - * Changes and refreshes the Application UI node handled by the sub parts. - */ - public void refreshUiApplicationNode() { - if (mOverviewPart != null) { - mOverviewPart.onSdkChanged(); - } - - if (mOverviewLinkPart != null) { - mOverviewLinkPart.onSdkChanged(); - } - - if (mTreeBlock != null) { - UiElementNode manifest = mEditor.getUiRootNode(); - mTreeBlock.changeRootAndDescriptors(manifest, - computeManifestExtraFilters(), - true /* refresh */); - } - } - - private ElementDescriptor[] computeManifestExtraFilters() { - UiElementNode manifest = mEditor.getUiRootNode(); - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - - if (manifestDescriptor == null) { - return null; - } - - // get the elements we want to exclude - HashSet<ElementDescriptor> excludes = new HashSet<ElementDescriptor>(); - excludes.add(manifestDescriptor.getApplicationElement()); - excludes.add(manifestDescriptor.getInstrumentationElement()); - excludes.add(manifestDescriptor.getPermissionElement()); - excludes.add(manifestDescriptor.getPermissionGroupElement()); - excludes.add(manifestDescriptor.getPermissionTreeElement()); - excludes.add(manifestDescriptor.getUsesPermissionElement()); - - // walk through the known children of the manifest descriptor and keep what's not excluded - ArrayList<ElementDescriptor> descriptorFilters = new ArrayList<ElementDescriptor>(); - for (ElementDescriptor child : manifest.getDescriptor().getChildren()) { - if (!excludes.contains(child)) { - descriptorFilters.add(child); - } - } - - if (descriptorFilters.size() == 0) { - return null; - } - return descriptorFilters.toArray(new ElementDescriptor[descriptorFilters.size()]); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java deleted file mode 100644 index 2f655777a..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.editors.manifest.pages; - -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IPageImageProvider; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; -import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.forms.IManagedForm; -import org.eclipse.ui.forms.editor.FormPage; -import org.eclipse.ui.forms.widgets.ScrolledForm; - -/** - * Page for permissions settings, part of the AndroidManifest form editor. - * <p/> - * Useful reference: - * <a href="http://www.eclipse.org/articles/Article-Forms/article.html"> - * http://www.eclipse.org/articles/Article-Forms/article.html</a> - */ -public final class PermissionPage extends FormPage implements IPageImageProvider { - /** Page id used for switching tabs programmatically */ - public final static String PAGE_ID = "permission_page"; //$NON-NLS-1$ - - /** Container editor */ - ManifestEditor mEditor; - - private UiTreeBlock mTreeBlock; - - public PermissionPage(ManifestEditor editor) { - super(editor, PAGE_ID, "Permissions"); // tab label, keep it short - mEditor = editor; - } - - @Override - public Image getPageImage() { - return IconFactory.getInstance().getIcon(getTitle(), - IconFactory.COLOR_RED, - IconFactory.SHAPE_RECT); - } - - /** - * Creates the content in the form hosted in this page. - * - * @param managedForm the form hosted in this page. - */ - @Override - protected void createFormContent(IManagedForm managedForm) { - super.createFormContent(managedForm); - ScrolledForm form = managedForm.getForm(); - form.setText("Android Manifest Permissions"); - form.setImage(AdtPlugin.getAndroidLogo()); - - UiElementNode manifest = mEditor.getUiRootNode(); - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - - ElementDescriptor[] descriptorFilters = null; - if (manifestDescriptor != null) { - descriptorFilters = new ElementDescriptor[] { - manifestDescriptor.getPermissionElement(), - manifestDescriptor.getUsesPermissionElement(), - manifestDescriptor.getPermissionGroupElement(), - manifestDescriptor.getPermissionTreeElement() - }; - } - mTreeBlock = new UiTreeBlock(mEditor, manifest, - true /* autoCreateRoot */, - descriptorFilters, - "Permissions", - "List of permissions defined and used by the manifest"); - mTreeBlock.createContent(managedForm); - } - - /** - * Changes and refreshes the Application UI node handled by the sub parts. - */ - public void refreshUiNode() { - if (mTreeBlock != null) { - UiElementNode manifest = mEditor.getUiRootNode(); - AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors(); - - mTreeBlock.changeRootAndDescriptors(manifest, - new ElementDescriptor[] { - manifestDescriptor.getPermissionElement(), - manifestDescriptor.getUsesPermissionElement(), - manifestDescriptor.getPermissionGroupElement(), - manifestDescriptor.getPermissionTreeElement() - }, - true /* refresh */); - } - } -} |