1f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael/*
2f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * Copyright (C) 2009 The Android Open Source Project
3f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael *
4f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * you may not use this file except in compliance with the License.
6f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * You may obtain a copy of the License at
7f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael *
8f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael *      http://www.eclipse.org/org/documents/epl-v10.php
9f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael *
10f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * Unless required by applicable law or agreed to in writing, software
11f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * distributed under the License is distributed on an "AS IS" BASIS,
12f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * See the License for the specific language governing permissions and
14f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * limitations under the License.
15f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael */
16f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
1769425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetpackage com.android.ide.eclipse.adt.internal.editors.manifest.model;
18f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
1981cefe2a26dd6db8a878e30874d12cdcbff0e83bXavier Ducrohetimport com.android.ide.common.xml.ManifestData;
20f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport com.android.ide.eclipse.adt.AdtPlugin;
2169425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
2269425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
2369425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
2469425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
2569425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
2669425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetimport com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
27d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
28f2880494706ad8dfd43e21471096216be4ca7c69Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
29d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.project.ProjectHelper;
30f2880494706ad8dfd43e21471096216be4ca7c69Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction;
31f2880494706ad8dfd43e21471096216be4ca7c69Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard;
32f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
33f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.core.resources.IFile;
34f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jdt.core.IJavaProject;
35f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jface.dialogs.Dialog;
36f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jface.dialogs.IMessageProvider;
37f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jface.viewers.ILabelProvider;
38f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jface.viewers.ILabelProviderListener;
39f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.jface.window.Window;
40f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.SWT;
41f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.DisposeEvent;
42f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.DisposeListener;
43f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.ModifyEvent;
44f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.ModifyListener;
45f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.SelectionAdapter;
46f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.events.SelectionEvent;
47f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.graphics.Image;
48f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.layout.GridData;
49f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.layout.GridLayout;
50f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.widgets.Button;
51f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.widgets.Composite;
52f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.swt.widgets.Text;
53f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.IWorkbenchPage;
54f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.IWorkbenchWindow;
55f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.PartInitException;
56f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.PlatformUI;
57f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.dialogs.ElementListSelectionDialog;
58f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.IManagedForm;
59f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.events.HyperlinkAdapter;
60f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.events.HyperlinkEvent;
61f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.widgets.FormText;
62f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.widgets.FormToolkit;
63f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.forms.widgets.TableWrapData;
64f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport org.eclipse.ui.part.FileEditorInput;
65f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
66f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelimport java.util.TreeSet;
67f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
68f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael/**
692e9be3365117d1ece3989cce4bb7ef0421df7343Tor Norbye * Represents an XML attribute to select an existing manifest package, that can be modified using
70f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * a simple text field or a dialog to choose an existing package.
71f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * <p/>
72f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael * See {@link UiTextAttributeNode} for more information.
73f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael */
74f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphaelpublic class UiManifestPkgAttrNode extends UiTextAttributeNode {
75f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
76f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
77f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Creates a {@link UiManifestPkgAttrNode} object that will display ui to select or create
78f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * a manifest package.
79f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node.
80f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
81f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    public UiManifestPkgAttrNode(AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
82f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        super(attributeDescriptor, uiParent);
83f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
84f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
85f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /* (non-java doc)
86f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Creates a label widget and an associated text field.
87f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * <p/>
88f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * As most other parts of the android manifest editor, this assumes the
89f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * parent uses a table layout with 2 columns.
90f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
91f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    @Override
92f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    public void createUiControl(final Composite parent, final IManagedForm managedForm) {
93f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        setManagedForm(managedForm);
94f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        FormToolkit toolkit = managedForm.getToolkit();
95f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        TextAttributeDescriptor desc = (TextAttributeDescriptor) getDescriptor();
96f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
97f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        StringBuilder label = new StringBuilder();
98f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        label.append("<form><p><a href='unused'>");  //$NON-NLS-1$
99f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        label.append(desc.getUiName());
100f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        label.append("</a></p></form>");  //$NON-NLS-1$
101f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        FormText formText = SectionHelper.createFormText(parent, toolkit, true /* isHtml */,
102f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                label.toString(), true /* setupLayoutData */);
103f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        formText.addHyperlinkListener(new HyperlinkAdapter() {
104f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            @Override
105f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            public void linkActivated(HyperlinkEvent e) {
106f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                super.linkActivated(e);
107f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                doLabelClick();
108f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
109f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        });
110f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
111f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        SectionHelper.addControlTooltip(formText, desc.getTooltip());
1127641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
113f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        Composite composite = toolkit.createComposite(parent);
114f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
115f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        GridLayout gl = new GridLayout(2, false);
116f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        gl.marginHeight = gl.marginWidth = 0;
117f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        composite.setLayout(gl);
118f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // Fixes missing text borders under GTK... also requires adding a 1-pixel margin
119f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // for the text field below
120f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        toolkit.paintBordersFor(composite);
1217641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
122f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        final Text text = toolkit.createText(composite, getCurrentValue());
123f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
124f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        gd.horizontalIndent = 1;  // Needed by the fixed composite borders under GTK
125f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        text.setLayoutData(gd);
126f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
127f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        setTextWidget(text);
128f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
129f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
1307641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
131f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        browseButton.addSelectionListener(new SelectionAdapter() {
132f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            @Override
133f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            public void widgetSelected(SelectionEvent e) {
134f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                super.widgetSelected(e);
135f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                doBrowseClick();
136f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
137f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        });
1387641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
139f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
1407641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
141f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /* (non-java doc)
142f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Adds a validator to the text field that calls managedForm.getMessageManager().
143f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
144f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    @Override
145f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    protected void onAddValidators(final Text text) {
146f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        ModifyListener listener = new ModifyListener() {
147ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye            @Override
148f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            public void modifyText(ModifyEvent e) {
149f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                String package_name = text.getText();
150f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                if (package_name.indexOf('.') < 1) {
151f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    getManagedForm().getMessageManager().addMessage(text,
152f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                            "Package name should contain at least two identifiers.",
153f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                            null /* data */, IMessageProvider.ERROR, text);
154f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                } else {
155f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    getManagedForm().getMessageManager().removeMessage(text, text);
156f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                }
157f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
158f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        };
159f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
160f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        text.addModifyListener(listener);
161f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
162f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // Make sure the validator removes its message(s) when the widget is disposed
163f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        text.addDisposeListener(new DisposeListener() {
164ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye            @Override
165f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            public void widgetDisposed(DisposeEvent e) {
166f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                getManagedForm().getMessageManager().removeMessage(text, text);
167f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
168f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        });
169f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
170f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // Finally call the validator once to make sure the initial value is processed
171f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        listener.modifyText(null);
172f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
173f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
174f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
175f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Handles response to the Browse button by creating a Package dialog.
176f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * */
177f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    private void doBrowseClick() {
1787641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
179f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // Display the list of AndroidManifest packages in a selection dialog
180f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        ElementListSelectionDialog dialog = new ElementListSelectionDialog(
181f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                getTextWidget().getShell(),
182f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                new ILabelProvider() {
183ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
184f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public Image getImage(Object element) {
185f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        return null;
186f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
187f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
188ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
189f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public String getText(Object element) {
190f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        return element.toString();
191f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
192f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
193ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
194f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public void addListener(ILabelProviderListener listener) {
195f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
196f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
197ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
198f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public void dispose() {
199f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
200f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
201ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
202f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public boolean isLabelProperty(Object element, String property) {
203f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        return false;
204f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
205f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
206ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye                    @Override
207f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    public void removeListener(ILabelProviderListener listener) {
208f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
209f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                });
210f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
211f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        dialog.setTitle("Android Manifest Package Selection");
212f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        dialog.setMessage("Select the Android Manifest package to target.");
213f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
214f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        dialog.setElements(getPossibleValues(null));
215f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
216f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // open the dialog and use the object selected if OK was clicked, or null otherwise
217f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        if (dialog.open() == Window.OK) {
218f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            String result = (String) dialog.getFirstResult();
219f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            if (result != null && result.length() > 0) {
220f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                getTextWidget().setText(result);
221f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
222f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        }
223f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
224f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
225f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
226f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Handles response to the Label hyper link being activated.
227f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
228f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    private void doLabelClick() {
229f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // get the current package name
230f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        String package_name = getTextWidget().getText().trim();
2317641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet
232f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        if (package_name.length() == 0) {
233f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            createNewProject();
234f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        } else {
235f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            displayExistingManifest(package_name);
236f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        }
237f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
238f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
239f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
240f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * When the label is clicked and there's already a package name, this method
241f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * attempts to find the project matching the android package name and it attempts
242f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * to open the manifest editor.
2437641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet     *
244f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * @param package_name The android package name to find. Must not be null.
245f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
246f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    private void displayExistingManifest(String package_name) {
247f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
248f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        // Look for the first project that uses this package name
2497641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet        for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) {
250f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            // check that there is indeed a manifest file.
251d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            IFile manifestFile = ProjectHelper.getManifest(project.getProject());
252f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            if (manifestFile == null) {
253f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                // no file? skip this project.
254f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                continue;
255f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
256f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
257d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            ManifestData manifestData = AndroidManifestHelper.parseForData(manifestFile);
258d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            if (manifestData == null) {
259f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                // skip this project.
260f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                continue;
261f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
262f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
263d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            if (package_name.equals(manifestData.getPackage())) {
2647641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet                // Found the project.
265f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
266f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
267f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                if (win != null) {
268f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    IWorkbenchPage page = win.getActivePage();
269f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    if (page != null) {
270f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        try {
271f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                            page.openEditor(
272f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    new FileEditorInput(manifestFile),
273f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    ManifestEditor.ID,
274f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    true, /* activate */
275f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    IWorkbenchPage.MATCH_INPUT);
276f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        } catch (PartInitException e) {
277f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                            AdtPlugin.log(e,
278f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    "Opening editor failed for %s",  //$NON-NLS-1$
279f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                                    manifestFile.getFullPath());
280f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                        }
281f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                    }
282f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                }
283f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
284f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                // We found the project; even if we failed there's no need to keep looking.
285f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                return;
286f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
287f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        }
288f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
289f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
290f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
291f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Displays the New Project Wizard to create a new project.
292f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * If one is successfully created, use the Android Package name.
293f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
294f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    private void createNewProject() {
295f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
296f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        NewProjectAction npwAction = new NewProjectAction();
297f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        npwAction.run(null /*action*/);
298f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        if (npwAction.getDialogResult() == Dialog.OK) {
299f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            NewProjectWizard npw = (NewProjectWizard) npwAction.getWizard();
300f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            String name = npw.getPackageName();
301f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            if (name != null && name.length() > 0) {
302f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                getTextWidget().setText(name);
303f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
304f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        }
305f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
306f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
307f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    /**
308f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * Returns all the possible android package names that could be used.
309f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * The prefix is not used.
3107641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet     *
311f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     * {@inheritDoc}
312f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael     */
313f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    @Override
314f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    public String[] getPossibleValues(String prefix) {
315f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        TreeSet<String> packages = new TreeSet<String>();
316f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
3177641cd7668c2dda9d198cc660d58d845de677029Xavier Ducrohet        for (IJavaProject project : BaseProjectHelper.getAndroidProjects(null /*filter*/)) {
318f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            // check that there is indeed a manifest file.
319d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            ManifestData manifestData = AndroidManifestHelper.parseForData(project.getProject());
320d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            if (manifestData == null) {
321f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                // skip this project.
322f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael                continue;
323f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael            }
324f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
325d5579c79e7dcb1eda9835f5a2c7299be7eab28b0Xavier Ducrohet            packages.add(manifestData.getPackage());
326f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        }
327f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
328f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael        return packages.toArray(new String[packages.size()]);
329f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael    }
330f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael}
331f63f5bea4d1f5c4a55790c7e85c5cadc5867e35aRaphael
332