Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java')
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java368
1 files changed, 368 insertions, 0 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java
new file mode 100644
index 0000000000..31ba898153
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal.widgets;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
+import org.eclipse.jdt.internal.ui.wizards.NewClassCreationWizard;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ClassName;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+
+/**
+ * This chooser allows the user to choose a type when browsing and it adds code
+ * completion support to the text field, which is the main component.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ---------------------------------------------------- ------------- |
+ * | Label: | I | | Browse... | |
+ * | ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class ClassChooserPane<T extends Model> extends ChooserPane<T>
+{
+ /**
+ * The code completion manager.
+ */
+ protected JavaTypeCompletionProcessor javaTypeCompletionProcessor;
+
+ private PropertyChangeListener subjectChangeListener;
+
+ /**
+ * Creates a new <code>ClassChooserPane</code>.
+ *
+ * @param parentPane The parent pane of this one
+ * @param parent The parent container
+ */
+ public ClassChooserPane(Pane<? extends T> parentPane,
+ Composite parent) {
+
+ super(parentPane, parent);
+ }
+
+ /**
+ * Creates a new <code>ClassChooserPane</code>.
+ *
+ * @param parentPane The parent container of this one
+ * @param subjectHolder The holder of this pane's subject
+ * @param parent The parent container
+ */
+ public ClassChooserPane(Pane<?> parentPane,
+ PropertyValueModel<? extends T> subjectHolder,
+ Composite parent) {
+
+ super(parentPane, subjectHolder, parent);
+ }
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+
+ // TODO bug 156185 - when this is fixed there should be api for this
+ this.javaTypeCompletionProcessor = new JavaTypeCompletionProcessor(false, false);
+
+ this.subjectChangeListener = this.buildSubjectChangeListener();
+ this.getSubjectHolder().addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+
+ this.classChooserSubjectChanged(getSubject());
+ }
+
+ private PropertyChangeListener buildSubjectChangeListener() {
+ return new SWTPropertyChangeListenerWrapper(this.buildSubjectChangeListener_());
+ }
+
+ private PropertyChangeListener buildSubjectChangeListener_() {
+ return new PropertyChangeListener() {
+ @SuppressWarnings("unchecked")
+ public void propertyChanged(PropertyChangeEvent e) {
+ ClassChooserPane.this.classChooserSubjectChanged((T) e.getNewValue());
+ }
+ };
+ }
+
+ protected void classChooserSubjectChanged(T newSubject) {
+ IPackageFragment packageFragment = null;
+ if (newSubject != null) {
+ IPackageFragmentRoot root = getPackageFragmentRoot();
+ if (root != null) {
+ packageFragment = root.getPackageFragment("");
+ }
+ }
+ this.javaTypeCompletionProcessor.setPackageFragment(packageFragment);
+ }
+
+ @Override
+ protected Control addLeftControl(Composite container) {
+ if( ! this.allowTypeCreation()) {
+ return super.addLeftControl(container);
+ }
+ Hyperlink labelLink = this.addHyperlink(container,
+ this.getLabelText(),
+ this.buildHyperLinkAction()
+ );
+ return labelLink;
+ }
+
+ private Runnable buildHyperLinkAction() {
+ return new Runnable() {
+ public void run() {
+ ClassChooserPane.this.hyperLinkSelected();
+ }
+ };
+ }
+
+ protected void hyperLinkSelected() {
+ IType type = getType();
+ if (type != null) {
+ openInEditor(type);
+ }
+ else if (allowTypeCreation()){
+ createType();
+ }
+ }
+
+ protected IType getType() {
+ if (getClassName() == null) {
+ return null;
+ }
+ IType type = null;
+ try {
+ type = getJpaProject().getJavaProject().findType(getClassName().replace('$', '.'));
+ }
+ catch (JavaModelException e) {
+ JptUiPlugin.log(e);
+ }
+ return type;
+ }
+
+ protected void createType() {
+ StructuredSelection selection = new StructuredSelection(getJpaProject().getProject());
+
+ NewClassWizardPage newClassWizardPage = new NewClassWizardPage();
+ newClassWizardPage.init(selection);
+ newClassWizardPage.setSuperClass(getSuperclassName(), true);
+ newClassWizardPage.setSuperInterfaces(getSuperInterfaceNames(), true);
+ if (!StringTools.stringIsEmpty(getClassName())) {
+ newClassWizardPage.setTypeName(ClassName.getSimpleName(getClassName()), true);
+ String packageName = ClassName.getPackageName(getClassName());
+ newClassWizardPage.setPackageFragment(getFirstJavaSourceFolder().getPackageFragment(packageName), true);
+ }
+ NewClassCreationWizard wizard = new NewClassCreationWizard(newClassWizardPage, false);
+ wizard.init(PlatformUI.getWorkbench(), selection);
+
+ WizardDialog dialog = new WizardDialog(getShell(), wizard);
+ dialog.create();
+ int dResult = dialog.open();
+ if (dResult == Window.OK) {
+ String className = (newClassWizardPage.getCreatedType()).getFullyQualifiedName(getEnclosingTypeSeparator());
+ setClassName(className);
+ }
+ }
+
+ protected abstract void setClassName(String className);
+
+ /**
+ * Override this to change the enclosing type separator
+ */
+ protected char getEnclosingTypeSeparator() {
+ return '$';
+ }
+
+ /**
+ * Override this to set a superclass in the New Class wizard. If no class is chosen,
+ * clicking the hyperlink label will open the new class wizard.
+ */
+ protected String getSuperclassName() {
+ return "";
+ }
+
+ /**
+ * Override this to set a super interface in the New Class wizard. If no class is chosen,
+ * clicking the hyperlink label will open the new class wizard.
+ * @see getSuperInterfaceName
+ */
+ protected List<String> getSuperInterfaceNames() {
+ return getSuperInterfaceName() != null ? Collections.singletonList(getSuperInterfaceName()) : Collections.<String>emptyList();
+ }
+
+ /**
+ * Override this to set a super interface in the New Class wizard. If no class is chosen,
+ * clicking the hyperlink label will open the new class wizard.
+ */
+ protected String getSuperInterfaceName() {
+ return null;
+ }
+
+ /**
+ * Override this if it does not make sense to allow the user to create a new type.
+ * This will determine whether clicking the hyperlink opens the New Class wizard
+ * @return
+ */
+ protected boolean allowTypeCreation() {
+ return true;
+ }
+
+ protected void openInEditor(IType type) {
+ IJavaElement javaElement = type.getParent();
+ try {
+ JavaUI.openInEditor(javaElement, true, true);
+ }
+ catch (JavaModelException e) {
+ JptUiPlugin.log(e);
+ }
+ catch (PartInitException e) {
+ JptUiPlugin.log(e);
+ }
+ }
+
+ protected abstract JpaProject getJpaProject();
+
+ @Override
+ protected final Runnable buildBrowseAction() {
+ return new Runnable() {
+ public void run() {
+ promptType();
+ }
+ };
+ }
+
+ @Override
+ protected Control addMainControl(Composite container) {
+ Composite subPane = addSubPane(container);
+ Text text = addText(subPane, buildTextHolder());
+
+ ControlContentAssistHelper.createTextContentAssistant(
+ text,
+ javaTypeCompletionProcessor
+ );
+
+ return subPane;
+ }
+
+ /**
+ * Creates the value holder of the subject's property.
+ *
+ * @return The holder of the class name
+ */
+ protected abstract WritablePropertyValueModel<String> buildTextHolder();
+
+ /**
+ * Prompts the user the Open Type dialog.
+ *
+ * @return Either the selected type or <code>null</code> if the user
+ * cancelled the dialog
+ */
+ protected IType chooseType() {
+ IJavaElement[] elements = new IJavaElement[] { getJpaProject().getJavaProject() };
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(elements);
+ SelectionDialog typeSelectionDialog;
+
+ try {
+ typeSelectionDialog = JavaUI.createTypeDialog(
+ getShell(),
+ PlatformUI.getWorkbench().getProgressService(),
+ scope,
+ getTypeDialogStyle(),
+ false,
+ StringTools.stringIsEmpty(getClassName()) ? "" : ClassName.getSimpleName(getClassName())
+ );
+ }
+ catch (JavaModelException e) {
+ JptUiPlugin.log(e);
+ return null;
+ }
+
+ typeSelectionDialog.setTitle(JptUiMessages.ClassChooserPane_dialogTitle);
+ typeSelectionDialog.setMessage(JptUiMessages.ClassChooserPane_dialogMessage);
+
+ if (typeSelectionDialog.open() == Window.OK) {
+ return (IType) typeSelectionDialog.getResult()[0];
+ }
+
+ return null;
+ }
+
+ protected int getTypeDialogStyle() {
+ return IJavaElementSearchConstants.CONSIDER_CLASSES;
+ }
+
+ /**
+ * Returns the class name from its subject.
+ *
+ * @return The class name or <code>null</code> if none is defined
+ */
+ protected abstract String getClassName();
+
+ protected IPackageFragmentRoot getFirstJavaSourceFolder() {
+ Iterator<IPackageFragmentRoot> i = JDTTools.getJavaSourceFolders(getJpaProject().getJavaProject()).iterator();
+ return i.hasNext() ? i.next() : null;
+ }
+
+ /**
+ * The browse button was clicked, its action invokes this action which should
+ * prompt the user to select a class and set it.
+ */
+ protected void promptType() {
+ IType type = this.chooseType();
+
+ if (type != null) {
+ String className = type.getFullyQualifiedName(getEnclosingTypeSeparator());
+ setClassName(className);
+ }
+ }
+
+ protected IPackageFragmentRoot getPackageFragmentRoot() {
+ return JDTTools.getCodeCompletionContextRoot(getJpaProject().getJavaProject());
+ }
+
+ @Override
+ public void dispose() {
+ this.getSubjectHolder().removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+ super.dispose();
+ }
+} \ No newline at end of file

Back to the top