aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java321
1 files changed, 321 insertions, 0 deletions
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
new file mode 100644
index 000000000..e6a2007b3
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java
@@ -0,0 +1,321 @@
+/*
+ * 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;
+ }
+}
+