summaryrefslogtreecommitdiff
path: root/src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java')
-rw-r--r--src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java656
1 files changed, 656 insertions, 0 deletions
diff --git a/src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java b/src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java
new file mode 100644
index 0000000..72bb4e5
--- /dev/null
+++ b/src/plugins/android.codeutils/src/com/motorola/studio/android/generatemenucode/ui/GenerateMenuCodeDialog.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.motorola.studio.android.generatemenucode.ui;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+import com.motorola.studio.android.codeutils.CodeUtilsActivator;
+import com.motorola.studio.android.codeutils.i18n.CodeUtilsNLS;
+import com.motorola.studio.android.common.IAndroidConstants;
+import com.motorola.studio.android.common.exception.AndroidException;
+import com.motorola.studio.android.common.log.StudioLogger;
+import com.motorola.studio.android.generatecode.JDTUtils;
+import com.motorola.studio.android.generatemenucode.model.codegenerators.CodeGeneratorDataBasedOnMenu;
+import com.motorola.studio.android.generatemenucode.model.codegenerators.JavaModifierBasedOnMenu;
+
+/**
+ * Dialog to generate code to deal with Android menus base on a selected menu.xml file
+ */
+public class GenerateMenuCodeDialog extends TitleAreaDialog
+{
+
+ private ICompilationUnit javaFile;
+
+ private IProject javaProject = null;
+
+ private JavaModifierBasedOnMenu modifier;
+
+ private Combo projectNameComboBox;
+
+ private Combo classNameComboBox;
+
+ private Combo menuFileNameComboBox;
+
+ private String menuFileErrorMessage;
+
+ private final String helpID = CodeUtilsActivator.PLUGIN_ID
+ + ".generate-code-from-context-menu-dialog"; //$NON-NLS-1$
+
+ private Image image = null;
+
+ private List<IType> availableFragmentClasses = null;
+
+ private final String defaultMessage;
+
+ private final String title;
+
+ private final String shellTitle;
+
+ /**
+ * Default constructor for the dialog
+ * @param parentShell shell to open the dialog
+ * @param description text to show dialog
+ * @param title text
+ * @param shellTitle window text
+ * @param image icon to show in the dialog
+ */
+ public GenerateMenuCodeDialog(Shell parentShell, String description, String title,
+ String shellTitle, Image image)
+ {
+ super(parentShell);
+ this.defaultMessage = description != null ? description : ""; //$NON-NLS-1$
+ this.title = title != null ? title : ""; //$NON-NLS-1$
+ this.shellTitle = shellTitle != null ? shellTitle : ""; //$NON-NLS-1$
+ this.image = image;
+ }
+
+ /**
+ * Set the initial values for project name and class name, if there is some selected.
+ * Also, set the modifier that will be used to generate code - the dialog set its codeGeneratorData
+ * according to the selected menu.
+ * @param modifier modifier that will have its codeGeneratorData set
+ * @param javaProject the project that will be selected when the dialog appears
+ * @param javaFile the class that will be selected when the dialog appears
+ * */
+ public void init(JavaModifierBasedOnMenu modifier, IProject javaProject, IFile javaFile)
+ {
+ setJavaModifier(modifier);
+ setJavaProject(javaProject);
+ setJavaFile(javaFile);
+ }
+
+ @Override
+ protected Control createContents(Composite parent)
+ {
+ Control c = super.createContents(parent);
+ setTitle(title);
+ if (image != null)
+ {
+ setTitleImage(image);
+ }
+ validate();
+ return c;
+ }
+
+ @Override
+ protected final Control createDialogArea(Composite parent)
+ {
+ if (helpID != null)
+ {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, helpID);
+ }
+ Composite parentComposite = (Composite) super.createDialogArea(parent);
+ Composite mainComposite = new Composite(parentComposite, SWT.NULL);
+ mainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mainComposite.setLayout(new GridLayout(2, false));
+ createProjectNameArea(mainComposite);
+ createClassNameArea(mainComposite);
+ createMenuFileNameArea(mainComposite);
+
+ Label separator = new Label(mainComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
+ separator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
+
+ return parentComposite;
+
+ }
+
+ /**
+ * Create GUI items for project name selection.
+ * @param optionsComposite
+ */
+ private void createProjectNameArea(Composite parent)
+ {
+ Label projectLabel = new Label(parent, SWT.NONE);
+ projectLabel.setText(CodeUtilsNLS.GenerateMenuCodeDialog_ProjectLabel);
+ projectLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+
+ projectNameComboBox = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN);
+ projectNameComboBox.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+ projectNameComboBox.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ setJavaProject((IProject) projectNameComboBox.getData(projectNameComboBox.getText()));
+ populateClasses();
+ populateMenuFileNames();
+ }
+ });
+ populateProjects();
+ }
+
+ /**
+ * Create GUI items for class name selection.
+ * @param parent
+ */
+ private void createClassNameArea(Composite parent)
+ {
+ Label classLabel = new Label(parent, SWT.NONE);
+ classLabel.setText(CodeUtilsNLS.GenerateMenuCodeDialog_TargetClassLabel);
+ classLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+
+ classNameComboBox = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN);
+ classNameComboBox.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+ classNameComboBox.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ setJavaFile(((IType) classNameComboBox.getData(classNameComboBox.getText()))
+ .getCompilationUnit());
+ populateMenuFileNames();
+ }
+ });
+ populateClasses();
+ }
+
+ /**
+ * Create GUI items for layout file name selection.
+ * @param parent
+ */
+ private void createMenuFileNameArea(Composite parent)
+ {
+ Label menuFileLabel = new Label(parent, SWT.NONE);
+ menuFileLabel.setText(CodeUtilsNLS.GenerateMenuCodeDialog_MenuFileLabel);
+ menuFileLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+
+ menuFileNameComboBox = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN);
+ menuFileNameComboBox.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+
+ menuFileNameComboBox.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ validateMenuFileNames(menuFileNameComboBox.getText());
+ }
+ });
+ populateMenuFileNames();
+
+ }
+
+ /**
+ * Populate the combobox that holds projects, with information gathered from the ResourcesPlugin.
+ * also selects the project set in the init method
+ */
+ private void populateProjects()
+ {
+ if (projectNameComboBox != null)
+ {
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ int i = 0, selectedProjectIndex = -1;
+
+ for (IProject prj : projects)
+ {
+ try
+ {
+ if (prj.hasNature(IAndroidConstants.ANDROID_NATURE))
+ {
+ projectNameComboBox.add(prj.getName());
+ projectNameComboBox.setData(prj.getName(), prj);
+ if ((javaProject != null) && prj.equals(javaProject))
+ {
+ selectedProjectIndex = i;
+ }
+ i++;
+ }
+ }
+ catch (CoreException e)
+ {
+ StudioLogger.info("Project nature could not be checked."); //$NON-NLS-1$
+ }
+ }
+
+ if (projectNameComboBox.getItemCount() > 0)
+ {
+ if (selectedProjectIndex == -1)
+ {
+ projectNameComboBox.select(0);
+ setJavaProject((IProject) projectNameComboBox.getData(projectNameComboBox
+ .getText()));
+ }
+ else
+ {
+ projectNameComboBox.select(selectedProjectIndex);
+ }
+ }
+
+ }
+ validate();
+ }
+
+ /**
+ * Populate the combobox that holds class names.
+ */
+ private void populateClasses()
+ {
+ if (classNameComboBox != null)
+ {
+ classNameComboBox.removeAll();
+ if (javaProject != null)
+ {
+ int i = 0, selectedTypeIndex = -1;
+ try
+ {
+ List<IType> availableClasses =
+ JDTUtils.getAvailableActivities(javaProject, new NullProgressMonitor());
+
+ //Fragment classes can have menu too, so add all fragment classes to menu combo box
+
+ if (availableFragmentClasses != null)
+ {
+ availableFragmentClasses.clear();
+ }
+ availableFragmentClasses =
+ JDTUtils.getAvailableFragmentsSubclasses((IProject) projectNameComboBox
+ .getData(projectNameComboBox.getText()),
+ new NullProgressMonitor());
+
+ availableClasses.addAll(availableFragmentClasses);
+
+ for (IType availableClass : availableClasses)
+ {
+ classNameComboBox.add(availableClass.getFullyQualifiedName());
+ classNameComboBox.setData(availableClass.getFullyQualifiedName(),
+ availableClass);
+ if ((getJavaFile() != null)
+ && availableClass.getCompilationUnit().equals(getJavaFile()))
+ {
+ selectedTypeIndex = i;
+ }
+ i++;
+ }
+ if (classNameComboBox.getItemCount() > 0)
+ {
+ if (selectedTypeIndex == -1)
+ {
+ classNameComboBox.select(0);
+ setJavaFile(((IType) classNameComboBox.getData(classNameComboBox
+ .getText())).getCompilationUnit());
+ }
+ else
+ {
+ classNameComboBox.select(selectedTypeIndex);
+ }
+ }
+ }
+ catch (JavaModelException e)
+ {
+ StudioLogger.info("Could not get available classes for the selected project"); //$NON-NLS-1$
+ }
+
+ classNameComboBox.setEnabled(classNameComboBox.getItemCount() > 0);
+ }
+ }
+ validate();
+ }
+
+ /**
+ * Validate the selected menu file of the combobox that holds menu file names.
+ */
+ protected void validateMenuFileNames(String menuFileName)
+ {
+ menuFileErrorMessage = null;
+
+ if ((menuFileNameComboBox != null)
+ && (menuFileNameComboBox.getData(menuFileName) instanceof String))
+ {
+ // If the data type is a String, it represents an error message.
+ menuFileErrorMessage = (String) menuFileNameComboBox.getData(menuFileName);
+ }
+
+ validate();
+ }
+
+ /**
+ * Populate the combobox that holds menu file names.
+ */
+ private void populateMenuFileNames()
+ {
+ if ((menuFileNameComboBox != null) && (getJavaFile() != null))
+ {
+ menuFileNameComboBox.removeAll();
+ menuFileErrorMessage = null;
+ CompilationUnit cpAstNode = JDTUtils.parse(getJavaFile());
+ if (!JDTUtils.hasErrorInCompilationUnitAstUtils(cpAstNode))
+ {
+ IProject prj =
+ (IProject) this.projectNameComboBox.getData(this.projectNameComboBox
+ .getText());
+
+ IFolder menuFolder =
+ prj.getFolder(IAndroidConstants.FD_RESOURCES).getFolder(
+ IAndroidConstants.FD_MENU);
+
+ String inflatedMenu =
+ JDTUtils.getInflatedMenuFileName(getJavaProject(), getJavaFile());
+
+ if ((inflatedMenu != null) && (inflatedMenu.length() > 0))
+ {
+ //the activity/fragment already inflates a menu
+ //select this menu on the combo box
+ try
+ {
+ inflatedMenu = inflatedMenu + '.' + IAndroidConstants.MENU_FILE_EXTENSION;
+ menuFileNameComboBox.add(inflatedMenu);
+ CodeGeneratorDataBasedOnMenu codeGeneratorData;
+ codeGeneratorData =
+ JDTUtils.createMenuFile(getJavaProject(), getJavaFile(),
+ inflatedMenu, getTypeAssociatedToJavaFile());
+
+ menuFileNameComboBox.setData(inflatedMenu, codeGeneratorData);
+ menuFileNameComboBox.select(0);
+
+ setMessage(CodeUtilsNLS.GenerateMenuCodeDialog_InflatedMessage,
+ IMessageProvider.NONE);
+
+ }
+ catch (AndroidException e)
+ {
+ menuFileErrorMessage = e.getMessage();
+ menuFileNameComboBox.setData(inflatedMenu, menuFileErrorMessage);
+ }
+
+ //Disable the menu combo box so the user cannot change the menu file
+ menuFileNameComboBox.select(0);
+ menuFileNameComboBox.setEnabled(false);
+ }
+ else
+ {
+ //there is no inflated menu
+
+ setMessage(defaultMessage, IMessageProvider.NONE);
+ //iterate over all files inside res/menu
+ try
+ {
+ for (IResource menuFile : menuFolder.members())
+ {
+ //only consider xml files
+ if ((menuFile.getType() == IResource.FILE)
+ && menuFile.getFileExtension().equals(
+ IAndroidConstants.MENU_FILE_EXTENSION))
+ {
+
+ menuFileNameComboBox.add(menuFile.getName());
+
+ try
+ {
+ CodeGeneratorDataBasedOnMenu codeGeneratorData =
+ JDTUtils.createMenuFile(getJavaProject(),
+ getJavaFile(), menuFile.getName(),
+ getTypeAssociatedToJavaFile());
+
+ menuFileNameComboBox.setData(menuFile.getName(),
+ codeGeneratorData);
+ }
+
+ catch (AndroidException e)
+ {
+ // The malformed xml files
+ menuFileErrorMessage = e.getMessage();
+ menuFileNameComboBox.setData(menuFile.getName(),
+ menuFileErrorMessage);
+ }
+
+ }
+ }
+ }
+ catch (CoreException e)
+ {
+ menuFileErrorMessage =
+ CodeUtilsNLS.GenerateMenuCodeDialog_Error_MenuFolderDoesNotExist;
+ }
+
+ menuFileNameComboBox.select(0); //if the combo box is empty, the selection is ignored
+ menuFileNameComboBox.setEnabled(menuFileNameComboBox.getItemCount() > 0);
+ }
+ }
+ else
+ {
+ menuFileErrorMessage = CodeUtilsNLS.GenerateMenuCodeDialog_Class_Error;
+ this.javaFile = null;
+ menuFileNameComboBox.setEnabled(false);
+ }
+ }
+ else
+ {
+ menuFileNameComboBox.setEnabled(false);
+ }
+ validate();
+ }
+
+ /**
+ * Retrieve the type ACTIVITY/FRAGMENT from the android class
+ * @return
+ */
+ private CodeGeneratorDataBasedOnMenu.TYPE getTypeAssociatedToJavaFile()
+ {
+ CodeGeneratorDataBasedOnMenu.TYPE type = CodeGeneratorDataBasedOnMenu.TYPE.ACTIVITY;
+ for (IType availableClass : availableFragmentClasses)
+ {
+ if (availableClass.getCompilationUnit().equals(getJavaFile()))
+ {
+ type = CodeGeneratorDataBasedOnMenu.TYPE.FRAGMENT;
+ break;
+ }
+ }
+ return type;
+ }
+
+ @Override
+ protected void configureShell(Shell newShell)
+ {
+ newShell.setSize(640, 280);
+ newShell.setText(shellTitle);
+ super.configureShell(newShell);
+ }
+
+ /**
+ * Validate the UI
+ * @return
+ */
+ protected void validate()
+ {
+
+ String errorMessage = null;
+
+ if ((projectNameComboBox != null) && (projectNameComboBox.getItemCount() == 0))
+ {
+ errorMessage = CodeUtilsNLS.GenerateMenuCodeDialog_NoSuitableProjects;
+ }
+ if ((errorMessage == null) && (classNameComboBox != null)
+ && (classNameComboBox.getItemCount() == 0))
+ {
+ errorMessage = CodeUtilsNLS.GenerateMenuCodeDialog_NoSuitableClasses;
+ }
+ if ((errorMessage == null) && (menuFileNameComboBox != null))
+ {
+ if ((menuFileErrorMessage != null)
+ && (menuFileNameComboBox.getSelectionIndex() >= 0)
+ && (menuFileNameComboBox.getData(menuFileNameComboBox
+ .getItem(menuFileNameComboBox.getSelectionIndex())) instanceof String))
+ {
+ errorMessage =
+ (String) menuFileNameComboBox.getData(menuFileNameComboBox
+ .getItem(menuFileNameComboBox.getSelectionIndex()));
+ }
+ else
+ {
+ if ((menuFileNameComboBox.getItemCount() == 0) && (getJavaFile() != null))
+ {
+ errorMessage = CodeUtilsNLS.GenerateMenuCodeDialog_NoSuitableMenus;
+ }
+ else if (getJavaFile() == null)
+ {
+ errorMessage = menuFileErrorMessage;
+ }
+ }
+ }
+
+ this.setMessage(errorMessage, IMessageProvider.ERROR);
+
+ if (errorMessage == null)
+ {
+ if ((this.getMessage() == null) || (this.getMessage().length() == 0))
+ {
+ this.setMessage(defaultMessage, IMessageProvider.NONE);
+ }
+ }
+
+ if (getButton(OK) != null)
+ {
+ getButton(OK)
+ .setEnabled(
+ (getErrorMessage() == null)
+ || ((getErrorMessage() != null) && (getErrorMessage().trim()
+ .isEmpty())));
+ }
+ }
+
+ private void setJavaFile(IFile javaFile)
+ {
+ if (javaFile != null)
+ {
+ setJavaFile(JavaCore.createCompilationUnitFrom(javaFile));
+ }
+ }
+
+ private void setJavaFile(ICompilationUnit javaFile)
+ {
+ this.javaFile = javaFile;
+ setJavaProject(javaFile.getJavaProject().getProject());
+ }
+
+ /**
+ * @return Compilation unit for the selected file (activity or fragment)
+ */
+ public ICompilationUnit getJavaFile()
+ {
+ return this.javaFile;
+ }
+
+ private void setJavaProject(IProject javaProject)
+ {
+ this.javaProject = javaProject;
+ }
+
+ private IProject getJavaProject()
+ {
+ return this.javaProject;
+ }
+
+ /**
+ * Returns CodeGeneratorDataBasedOnMenu according to the selected menu file, or null if no menu is selected.
+ * */
+ private CodeGeneratorDataBasedOnMenu getCodeGeneratorData()
+ {
+ CodeGeneratorDataBasedOnMenu result = null;
+ if (menuFileNameComboBox.getSelectionIndex() >= 0)
+ {
+ result =
+ (CodeGeneratorDataBasedOnMenu) this.menuFileNameComboBox
+ .getData(menuFileNameComboBox.getText());
+ }
+
+ return result;
+ }
+
+ /**
+ * @return the modifier responsible to modify the source code
+ */
+ public JavaModifierBasedOnMenu getJavaModifier()
+ {
+ return modifier;
+ }
+
+ /**
+ * @param modifier the modifier to set
+ */
+ public void setJavaModifier(JavaModifierBasedOnMenu modifier)
+ {
+ this.modifier = modifier;
+ }
+
+ @Override
+ protected void okPressed()
+ {
+ modifier.setCodeGeneratorData(getCodeGeneratorData());
+
+ super.okPressed();
+ }
+
+ /**
+ * Sets the focus of the content area of the dialog
+ */
+ public void setFocus()
+ {
+ this.getContents().setFocus();
+ }
+
+ @Override
+ protected boolean isResizable()
+ {
+ return true;
+ }
+} \ No newline at end of file