package org.mwc.cmap.core.ui_support;

import java.lang.reflect.Method;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public abstract class ThreadSafeDialog<T> extends
    org.eclipse.jface.dialogs.Dialog
{

  private T selection;

  protected ThreadSafeDialog(Shell parentShell)
  {
    super(parentShell);
  }

  protected abstract T internalOpenDialog();

  public T openDialog()
  {
    
    if(isUIThread())
    {

      return selection = internalOpenDialog();
      
    }
    
    final Object lock = new Object();

    final Display current = Display.getDefault();

    current.asyncExec(new Runnable()
    {
      public void run()
      {
        synchronized (lock)
        {
          try
          {
            selection = internalOpenDialog();
          }
          finally
          {
            lock.notify();
          }
        }
      }
    });

    synchronized (lock)
    {
      try
      {
        lock.wait();
      }
      catch (InterruptedException e)
      {
        e.printStackTrace();
      }
    }

    return selection;
  }

  public static boolean isUIThread()
  {
      Object uiThread = null;
      try
      {
          Class<?> displayClass = Display.class;
         
          Method getThreadMethod = displayClass.getDeclaredMethod("getThread", new Class[] { });
          uiThread = getThreadMethod.invoke(Display.getDefault(), new Object[] { });
      }
      catch(Exception e)
      {

        e.printStackTrace();
      }

      return (Thread.currentThread() == uiThread);
  }
  
}



@@ -66,16 +66,57 @@
 ethod;%0A%0A
+import org.eclipse.jface.dialogs.Dialog;%0A
 import o
@@ -190,97 +190,925 @@
 l;%0A%0A
-public abstract class ThreadSafeDialog%3CT%3E extends%0A    org.eclipse.jface.dialogs.Dialog%0A%7B%0A
+/**%0A * custom version of dialog class that opens without use of syncExec. We need to run dialogs async%0A * so that RCPTT runtime can interact with dialog controls.%0A *%0A * @author ian%0A *%0A * @param %3CT%3E%0A *          Return type%0A */%0Apublic abstract class ThreadSafeDialog%3CT%3E extends Dialog%0A%7B%0A%0A  /** are we on the UI thread?%0A   * %0A   * @return yes/no%0A   */%0A  private static boolean isUIThread()%0A  %7B%0A    Object uiThread = null;%0A    try%0A    %7B%0A      final Class%3C?%3E displayClass = Display.class;%0A%0A      final Method getThreadMethod = displayClass.getDeclaredMethod(%22getThread%22,%0A          new Class%5B%5D%0A          %7B%7D);%0A      uiThread = getThreadMethod.invoke(Display.getDefault(), new Object%5B%5D%0A      %7B%7D);%0A    %7D%0A    catch (final Exception e)%0A    %7B%0A%0A      e.printStackTrace();%0A    %7D%0A%0A    return (Thread.currentThread() == uiThread);%0A  %7D%0A%0A  /** we need to store the selection locally, so it can be passed into%0A   * the lock object%0A   */
 %0A  p
@@ -1157,16 +1157,22 @@
 eDialog(
+final 
 Shell pa
@@ -1215,16 +1215,111 @@
 );%0A  %7D%0A%0A
+  /** child classes should implement this to actually open the dialog%0A   * %0A   * @return%0A   */%0A
   protec
@@ -1380,24 +1380,89 @@
 ialog()%0A  %7B%0A
+    // if we're already on the UI thread we can just open dialog.
     %0A    if(
@@ -1460,16 +1460,17 @@
  %0A    if
+ 
 (isUIThr
@@ -1478,25 +1478,24 @@
 ad())%0A    %7B%0A
-%0A
       return
@@ -1533,25 +1533,14 @@
 ();%0A
-      %0A
     %7D%0A
-    
 %0A   
@@ -1665,24 +1665,40 @@
 ble()%0A    %7B%0A
+      @Override%0A
       public
@@ -2025,16 +2025,22 @@
  catch (
+final 
 Interrup
@@ -2102,25 +2102,24 @@
     %7D%0A    %7D%0A
-%0A
     return s
@@ -2137,476 +2137,6 @@
  %7D%0A%0A
-  public static boolean isUIThread()%0A  %7B%0A      Object uiThread = null;%0A      try%0A      %7B%0A          Class%3C?%3E displayClass = Display.class;%0A         %0A          Method getThreadMethod = displayClass.getDeclaredMethod(%22getThread%22, new Class%5B%5D %7B %7D);%0A          uiThread = getThreadMethod.invoke(Display.getDefault(), new Object%5B%5D %7B %7D);%0A      %7D%0A      catch(Exception e)%0A      %7B%0A%0A        e.printStackTrace();%0A      %7D%0A%0A      return (Thread.currentThread() == uiThread);%0A  %7D%0A  %0A%7D%0A%0A
+%7D
 %0A

Tidy implementation