diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java')
-rw-r--r-- | jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java | 147 |
1 files changed, 90 insertions, 57 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java index 0ca0e6a600..f70a5ad608 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/JptJpaUiPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Oracle. All rights reserved. + * Copyright (c) 2006, 2012 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. @@ -9,14 +9,13 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.ui; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; -import org.eclipse.jpt.jpa.core.JpaPlatform; -import org.eclipse.jpt.jpa.core.JptJpaCorePlugin; -import org.eclipse.jpt.jpa.ui.internal.platform.JpaPlatformUiRegistry; -import org.eclipse.jpt.jpa.ui.navigator.JpaNavigatorProvider; +import org.eclipse.jpt.common.utility.internal.AbstractBooleanReference; +import org.eclipse.jpt.jpa.core.JpaProjectManager; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Control; @@ -39,6 +38,10 @@ import org.osgi.framework.BundleContext; public class JptJpaUiPlugin extends AbstractUIPlugin { + /** + * @see #focusIn(Control) + */ + private final AsyncEventListenerFlag asyncEventListenerFlag = new AsyncEventListenerFlag(); private final Listener focusListener; @@ -50,8 +53,8 @@ public class JptJpaUiPlugin public static final String PLUGIN_ID = "org.eclipse.jpt.jpa.ui"; public static final String PLUGIN_ID_ = PLUGIN_ID + '.'; - private static final String FOCUS_DATA_KEY = PLUGIN_ID_ + "focus"; - private static final Object FOCUS_DATA = new Object(); + private static final String DALI_UI_KEY = PLUGIN_ID; + private static final Object DALI_UI_DATA = new Object(); // ********** Preference keys ********** @@ -169,70 +172,58 @@ public class JptJpaUiPlugin // ********** focus handling ********** /** - * This method is called whenever a "focus in" event is generated. - * If the control gaining focus is part of one of our composites (typically - * a JPA Details View), we stop listening to Java change events - * (and assume all changes to the Java model are generated by us). - * If the control gaining focus is *not* part of one of our composites, - * we start listening to the Java change events again. + * This method is called whenever a {@link SWT#FocusIn} event is generated. + * <p> + * If the control gaining focus is part of one the Dali composites + * (typically the JPA Details View), we deactivate the Dali Java change + * listener so we ignore any changes to the Java source code that probably + * originated from Dali. This means we will miss any changes to the Java + * source code that is caused by non-UI activity; but, we hope, these + * changes are unrelated to JPA annotations etc. + * <p> + * If the control gaining focus is <em>not</em> part of one of the Dali + * composites, we start listening to the Java change events again. This + * method is called whenever a non-Dali UI control gains the UI focus. When + * this happens we activate the Dali Java change listener so that we begin + * to keep the Dali model synchronized with the Java source code. */ - void focusIn(Control control) { - while (control != null) { - if (control.getData(FOCUS_DATA_KEY) == FOCUS_DATA) { - this.focusIn(); - return; - } - control = control.getParent(); - } - this.focusOut(); + /* CU private */ void focusIn(Control control) { + this.asyncEventListenerFlag.setValue(this.controlIsNonDali(control)); } /** - * This method is called whenever a Dali UI control that affects Java - * source code gains the UI focus. When this happens we deactivate - * the Dali Java change listener so we ignore any changes to the Java - * source code that probably originated from Dali. This means we will miss - * any changes to the Java source code that is caused by non-UI activity; - * but, we hope, these changes are unrelated to JPA annotations etc. - * @see #focusOut() + * Return whether the specified control is <em><b>neither</b></em> + * a Dali UI component <em><b>nor</b></em> contained by a Dali UI component. */ - private void focusIn() { - JptJpaCorePlugin.setJavaElementChangeListenerIsActive(false); + private boolean controlIsNonDali(Control control) { + return ! this.controlIsDali(control); } /** - * This method is called whenever a non-Dali UI control gains the UI focus. - * When this happens we activate the Dali Java change listener so that we - * begin to keep the Dali model synchronized with the Java source code. - * @see #focusIn() + * Return whether the specified control, or any of its ancestors, is a Dali + * UI component. + * + * @see #controlAffectsJavaSource(Control) */ - private void focusOut() { - JptJpaCorePlugin.setJavaElementChangeListenerIsActive(true); + private boolean controlIsDali(Control control) { + while (control != null) { + if (control.getData(DALI_UI_KEY) == DALI_UI_DATA) { + return true; + } + control = control.getParent(); + } + return false; } /** - * Tag the specified control so that whenever it (or any of its children, - * grandchildren, etc.) has the focus, the Dali model ignores any Java - * change events. This method is to be called when the control is first - * constructed. + * Tag the specified control so that whenever it (or any of its descendants) + * has the focus, the Dali model ignores any Java change events. This method + * is to be called when the control is first constructed. + * + * @see #controlIsDali(Control) */ public void controlAffectsJavaSource(Control control) { - control.setData(FOCUS_DATA_KEY, FOCUS_DATA); - } - - - // ********** platform ********** - - /** - * Return the JPA platform UI corresponding to the specified JPA platform. - */ - public JpaPlatformUi getJpaPlatformUi(JpaPlatform jpaPlatform) { - return JpaPlatformUiRegistry.instance().getJpaPlatformUi(jpaPlatform.getId()); - } - - public JpaNavigatorProvider getJpaNavigatorProvider(JpaPlatform jpaPlatform) { - JpaPlatformUi platform = this.getJpaPlatformUi(jpaPlatform); - return (platform == null) ? null : platform.getNavigatorProvider(); + control.setData(DALI_UI_KEY, DALI_UI_DATA); } @@ -245,9 +236,14 @@ public class JptJpaUiPlugin @Override public void start(BundleContext context) throws Exception { super.start(context); + this.getJpaProjectManager().addAsyncEventListenerFlag(this.asyncEventListenerFlag); Display.getDefault().addFilter(SWT.FocusIn, this.focusListener); } + private JpaProjectManager getJpaProjectManager() { + return (JpaProjectManager) ResourcesPlugin.getWorkspace().getAdapter(JpaProjectManager.class); + } + /** * Unregister our SWT listener with the display. */ @@ -255,9 +251,46 @@ public class JptJpaUiPlugin public void stop(BundleContext context) throws Exception { try { Display.getDefault().removeFilter(SWT.FocusIn, this.focusListener); + this.getJpaProjectManager().removeAsyncEventListenerFlag(this.asyncEventListenerFlag); } finally { super.stop(context); } } + + /** + * This flag's value depends on the current thread. If the current thread is + * the background Java Reconciler thread, the flag's value is determined by + * the current UI focus (i.e. whether the focus is somewhere other than a + * Dali view); otherwise the flag's value is <code>true</code>. + * In other words, if a Dali view has the focus and a Java event is fired + * on the Java Reconciler thread, the event is ignored; if the event is + * fired on some other thread (typically synchronously on the Main thread), + * the event is forwarded to the JPA projects. + */ + /* CU private */ static class AsyncEventListenerFlag + extends AbstractBooleanReference + { + private volatile boolean value = true; + + @SuppressWarnings("restriction") + private static final String JAVA_RECONCILER_THREAD_NAME = org.eclipse.jdt.internal.ui.text.JavaReconciler.class.getName(); + + AsyncEventListenerFlag() { + super(); + } + + public boolean getValue() { + if (Thread.currentThread().getName().equals(JAVA_RECONCILER_THREAD_NAME)) { + return this.value; + } + return true; + } + + public boolean setValue(boolean value) { + boolean old = this.value; + this.value = value; + return old; + } + } } |