PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java

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