@Before
  public void setup() {
    BaseUIBTestUtils.resetAll();
    IManager.Factory.getManager().setTextCommitStrategy(TextCommitStrategy.ON_MODIFY);
    IManager.Factory.getManager().setEditCellSingleClick(false);

    createModel();
    createView();
  }
  @Before
  public void before() {
    BaseUIBTestUtils.resetAll();
    IManager.Factory.getManager().setEditCellSingleClick(false);
    IManager.Factory.getManager().setAlternateRowColors(myEnable);

    createShop();
    createView();
    bindUI();
  }
  /**
   * Source values for a column binding for a simple feature after the previous column has been
   * deleted.
   */
  @Test
  public void testSimpleColumnBindingAfterDelete() {
    postMouse(myTable, 0 + myViewerBinding.getFirstTableColumnOffset(), 0);

    final IColumnBindingCellInformation ci =
        myViewerBinding.getCell(0, myViewerBinding.getList().get(1));
    assertNotNull(ci);

    /*
     * When the element is deleted, the current selected cell is changed, and this must be
     * monitored.
     */
    final MySourceProviderListener listener = new MySourceProviderListener();
    try {
      myProvider.addSourceProviderListener(listener);
      myContact1.setShop(null);
      yield();
    } finally {
      myProvider.removeSourceProviderListener(listener);
    }

    assertSource(Constants.SOURCES_THE_MANAGER, IManager.Factory.getManager());

    assertSource(Constants.SOURCES_ACTIVE_CONTEXT, myContext);

    assertSource(Constants.SOURCES_ACTIVE_CONTAINER_BINDING, myViewerBinding);
    assertSource(Constants.SOURCES_ACTIVE_BINDING, ci.getLabelBinding());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_RO, false);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_TYPE, "");
    assertSource(Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT, myContact2);
    assertSource(
        Constants.SOURCES_ACTIVE_BINDING_FEATURE, IMOAOPackage.Literals.NAMED_OBJECT__NAME);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE, myContact2.getName());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY, myContact2.getName());
  }
  /**
   * Adds any arguments from annotations.
   *
   * @param <ArgumentType> the argument type
   * @param context the argument context
   */
  protected <ArgumentType> void addEAnnotationArguments(IArgumentContext<ArgumentType> context) {
    final EAnnotation annotation = getEAnnotation();
    if (annotation == null) return;
    final String value = annotation.getDetails().get(context.getName());
    if (value == null) return;

    IManager.Factory.getManager().addArgumentValue(context, this, null, null, value);
  }
  @Before
  public void before() {
    resetAll();
    IManager.Factory.getManager().setTextCommitStrategy(TextCommitStrategy.ON_MODIFY);
    IManager.Factory.getManager().setEditCellSingleClick(false);

    createShop();
    createView();
    bindUI();

    final IServiceLocator locator = myContext.getServiceLocator();

    final ISourceProviderService sourceProviders =
        (ISourceProviderService) locator.getService(ISourceProviderService.class);

    myProvider = sourceProviders.getSourceProvider(Constants.SOURCES_ACTIVE_BINDING);

    myView.getSite().getPage().activate(myView);
    myBody.layout();
  }
  @Before
  public void before() {
    resetAll();
    IManager.Factory.getManager().setEditCellSingleClick(false);

    createModel();
    createView();
    bindUI();

    myView.getSite().getPage().activate(myView);
  }
  @Before
  public void before() {
    resetAll();
    IManager.Factory.getManager().setValidationDelay(VD);

    myView = UIBindingsTestUtils.createUIBTestView(this);

    myShop = ShopFactory.eINSTANCE.createShop();
    myShop.setName(myInitValue);

    myForm = myView.createFormCreator(myShop);
  }
  /** Source values for a non-binding widget */
  @Test
  public void testNoBinding() {
    myEmptyText.setFocus();
    // postMouse(myEmptyText, myEmptyText.getBounds());

    assertSource(Constants.SOURCES_THE_MANAGER, IManager.Factory.getManager());

    assertSource(Constants.SOURCES_ACTIVE_CONTEXT, IEvaluationContext.UNDEFINED_VARIABLE);

    assertSource(Constants.SOURCES_ACTIVE_BINDING, IEvaluationContext.UNDEFINED_VARIABLE);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE, IEvaluationContext.UNDEFINED_VARIABLE);
  }
  @Override
  public <ArgumentType> void addArguments(final IArgumentContext<ArgumentType> context) {
    if (!context.addDataType(this)) return;

    addEAnnotationArguments(context);
    if (context.isResultFound()) return;

    /*
     * Avoid recursion when resolving the "type" argument!!!
     */
    if (!Constants.ARG_TYPE.equals(context.getName())) {
      final String type = context.getType();
      if (type != null && type.length() > 0) {
        IManager.Factory.getManager()
            .addArgumentProviderArguments(this.getArgumentProvider(type), context);
        if (context.isResultFound()) return;
      }
    }
    IManager.Factory.getManager()
        .addArgumentProviderArguments(this.getArgumentProvider(null), context);
  }
  @Override
  public void initialize(IInitializationParticipantContext context, Object facet) {
    if (!(facet instanceof EReference)) return;
    final EReference ref = (EReference) facet;
    if (!ref.isRequired() || ref.isContainer()) return;

    final EObject object = context.getObject();

    if (ref.getUpperBound() != 1) {
      /*
       * A list
       */
      @SuppressWarnings("unchecked")
      final EList<? extends EObject> l =
          (EList<? extends EObject>) context.getStructuralFeature(ref);
      int missing = ref.getLowerBound() - l.size();
      if (missing < 0) return;

      final List<EObject> newChildren = new ArrayList<EObject>(missing);
      for (; missing > 0; missing--) {
        final EObject newChild = EcoreUtil.create(ref.getEReferenceType());
        context.addCommand(
            IManager.Factory.getManager()
                .initializeObject(context.getEditingDomain(), object, ref, newChild, false));
      }
      context.addCommand(AddCommand.create(context.getEditingDomain(), object, ref, newChildren));
    } else {
      /*
       * Simple object
       */
      final Object o = context.getStructuralFeature(ref);
      if (o != null) return;

      final EObject newChild = EcoreUtil.create(ref.getEReferenceType());
      context.addCommand(
          IManager.Factory.getManager()
              .initializeObject(context.getEditingDomain(), object, ref, newChild, true));
    }
  }
  /** Source values for a value binding widget */
  @Test
  public void testValueBinding() {
    myNameText.setFocus();
    // postMouse(myNameText, myNameText.getBounds());

    assertSource(Constants.SOURCES_THE_MANAGER, IManager.Factory.getManager());

    assertSource(Constants.SOURCES_ACTIVE_CONTEXT, myContext);

    assertSource(Constants.SOURCES_ACTIVE_BINDING, myNameBinding);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_RO, false);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_UNSETTABLE, false);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE, myContact1.getName());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY, myContact1.getName());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_TYPE, "");
    assertSource(Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT, myContact1);
  }
  /** Source values for a column binding for a reference feature */
  @Test
  public void testReferenceColumnBinding() {
    postMouse(myTable, 1 + myViewerBinding.getFirstTableColumnOffset(), 0);

    final IColumnBindingCellInformation ci =
        myViewerBinding.getCell(1, myViewerBinding.getList().get(0));
    assertNotNull(ci);

    assertSource(Constants.SOURCES_THE_MANAGER, IManager.Factory.getManager());

    assertSource(Constants.SOURCES_ACTIVE_CONTEXT, myContext);

    assertSource(Constants.SOURCES_ACTIVE_CONTAINER_BINDING, myViewerBinding);
    assertSource(Constants.SOURCES_ACTIVE_BINDING, ci.getLabelBinding());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_RO, false);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_FEATURE, ShopPackage.Literals.CONTACT__COUNTRY);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_TYPE, "");
    assertSource(Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT, myContact1);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE, myCountry1);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY, myCountry1.getAbbreviation());
  }
  /** Source values for a column binding for a simple feature */
  @Test
  public void testROColumnBinding() {
    postMouse(myTable, 2 + myViewerBinding.getFirstTableColumnOffset(), 1);

    final IColumnBindingCellInformation ci =
        myViewerBinding.getCell(2, myViewerBinding.getList().get(1));
    assertNotNull(ci);

    assertSource(Constants.SOURCES_THE_MANAGER, IManager.Factory.getManager());

    assertSource(Constants.SOURCES_ACTIVE_CONTEXT, myContext);

    assertSource(Constants.SOURCES_ACTIVE_CONTAINER_BINDING, myViewerBinding);
    assertSource(Constants.SOURCES_ACTIVE_BINDING, ci.getLabelBinding());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_RO, true);
    assertSource(
        Constants.SOURCES_ACTIVE_BINDING_FEATURE, IMOAOPackage.Literals.NAMED_OBJECT__NAME);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_TYPE, "");
    assertSource(Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT, myCountry2);
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE, myCountry2.getName());
    assertSource(Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY, myCountry2.getName());
  }
Example #14
0
  public ViewerToolBar(IViewerBinding viewer, int style) {
    myViewer = viewer;
    myStyle = style;

    // TODO: Check style

    myViewer.registerService(this);

    final IManager manager = IManager.Factory.getManager();
    myToolkit = manager.getFormToolkit();

    final IServiceLocator serviceLocator = getViewer().getContext().getServiceLocator();
    myCommandService = (ICommandService) serviceLocator.getService(ICommandService.class);
    myHandlerService = (IHandlerService) serviceLocator.getService(IHandlerService.class);
    myCommandImageService =
        (ICommandImageService) serviceLocator.getService(ICommandImageService.class);

    /*
     * Find the control of the viewer (a Table or Tree).
     *
     * Find the parent Composite.
     *
     * Add a new Composite (with a GridLayout) and reparent the control
     *
     * Then add the toolbar itself on the correct side of the control
     */
    final Control control = myViewer.getControl();
    final Composite parent = control.getParent();

    myComposite = myToolkit.createComposite(parent);
    myComposite.setLayoutData(control.getLayoutData());
    final GridLayout compLayout = new GridLayout(1, false);
    myComposite.setLayout(compLayout);

    control.setParent(myComposite);
    control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    myToolBar = new ToolBar(myComposite, SWT.FLAT | (style & (VERTICAL | HORIZONTAL)));
    if ((style & VERTICAL) != 0) {
      myToolBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, false));
      compLayout.numColumns = 2;
    } else {
      myToolBar.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
    }
    /*
     * Inlined from FormToolkit.adapt(Composite composite). Do not set focus though.
     */
    myToolBar.setBackground(myComposite.getBackground());
    myToolBar.setMenu(myComposite.getMenu());

    myViewer.registerWidget(myToolBar);

    /*
     * Add standard items
     */
    if ((style & ADD) != 0) {
      // TODO addItem(ADD, "");
    }
    if ((style & DELETE) != 0) {
      addItem(
          DELETE,
          IManager.Factory.getManager()
              .getCommandIDs()
              .get(IWorkbenchCommandConstants.EDIT_DELETE));
    }
    if ((style & UP) != 0) {
      addItem(UP, "com.rcpcompany.uibindings.commands.moveItemUp");
    }
    if ((style & DOWN) != 0) {
      addItem(DOWN, "com.rcpcompany.uibindings.commands.moveItemDown");
    }

    myComposite.layout(true);
  }
  @Override
  public <ArgumentType> List<IArgumentValue<ArgumentType>> getArguments(
      final String name,
      final String type,
      final Class<? extends ArgumentType> argumentType,
      final boolean firstOnly) {
    final List<IArgumentValue<ArgumentType>> results =
        new ArrayList<IArgumentValue<ArgumentType>>();

    final IArgumentInformation ai = IManager.Factory.getManager().getArgumentInformation(name);
    final Set<IBindingDataType> visitedDataTypes = new HashSet<IBindingDataType>();

    final IArgumentContext<ArgumentType> context =
        new IArgumentContext<ArgumentType>() {
          @Override
          public IBinding getBinding() {
            return null;
          }

          @Override
          public String getName() {
            return name;
          }

          @Override
          public IArgumentInformation getArgumentInformation() {
            return ai;
          }

          @Override
          public String getType() {
            return type;
          }

          @Override
          public Class<? extends ArgumentType> getArgumentType() {
            return argumentType;
          }

          @Override
          public boolean firstOnly() {
            return firstOnly;
          }

          @Override
          public void addResult(Object source, ArgumentType value) {
            results.add(new ArgumentValue<ArgumentType>(this, value));
          }

          @Override
          public boolean isResultFound() {
            return firstOnly() && !results.isEmpty();
          }

          @Override
          public boolean addDataType(IBindingDataType dataType) {
            return visitedDataTypes.add(dataType);
          }
        };

    addArguments(context);
    if (context.isResultFound()) return results;

    addSFSuperContainingClassArguments(context);
    if (context.isResultFound()) return results;

    addSuperDataTypeArguments(context);
    if (context.isResultFound()) return results;

    addParentDataTypeArguments(context);
    if (context.isResultFound()) return results;

    return results;
  }
  /**
   * Returns a Map with the current state for the specific event if specified.
   *
   * @param event the current event - possibly <code>null</code>
   * @return a Map with the current state
   */
  public Map<String, Object> getCurrentState(final Event event) {
    final Map<String, Object> map = new HashMap<String, Object>();
    final List<IObservableValue> values = new ArrayList<IObservableValue>();
    resetMap(map);
    if (event.type == SWT.MenuDetect) {
      // LogUtils.debug(event, "MenuDetect");
    }
    try {
      myLastBinding = IBindingContext.Factory.getBindingForWidget(event.widget);
      if (myLastBinding == null) return map;

      map.put(Constants.SOURCES_ACTIVE_CONTEXT, myLastBinding.getContext());

      final ISourceProviderStateContext context =
          new ISourceProviderStateContext() {
            @Override
            public Event getEvent() {
              return event;
            }

            private Point myLocation = null;

            @Override
            public Point getLocation() {
              if (myLocation == null) {
                myLocation = new Point(event.x, event.y);
                switch (event.type) {
                  case SWT.MenuDetect:
                    /*
                     * The location is relative to the display
                     */
                    myLocation =
                        event.widget.getDisplay().map(null, (Control) event.widget, myLocation);
                    break;
                  default:
                    break;
                }
              }
              return myLocation;
            }

            @Override
            public Map<String, Object> getState() {
              return map;
            }

            @Override
            public void putSourceValue(String name, Object value) {
              map.put(name, value);
            }

            @Override
            public void addObservedValue(IObservableValue value) {
              values.add(value);
            }

            @Override
            public void setSelectionProvider(ISelectionProvider provider) {
              if (provider == myCurrentSelectionProvider) return;
              if (myCurrentSelectionProvider != null) {
                myCurrentSelectionProvider.removeSelectionChangedListener(
                    myCurrentSelectionProviderListener);
              }
              myCurrentSelectionProvider = provider;
              if (myCurrentSelectionProvider != null) {
                myCurrentSelectionProvider.addSelectionChangedListener(
                    myCurrentSelectionProviderListener);
              }
            }
          };
      try {
        myLastBinding.updateSourceProviderState(context);
      } catch (final Exception ex) {
        LogUtils.error(myLastBinding, ex);
      }

      /*
       * If the active binding is a value binding, run all extenders as well...
       */
      final Object activeBinding = map.get(Constants.SOURCES_ACTIVE_BINDING);
      if (activeBinding instanceof IValueBinding) {
        final IValueBinding vb = (IValueBinding) activeBinding;
        for (final IUIBindingDecoratorExtenderDescriptor d :
            IManager.Factory.getManager().getDecoratorExtenders()) {
          final CEObjectHolder<IUIBindingDecoratorExtender> factory = d.getFactory();
          final IUIBindingDecoratorExtender extender = factory.getObject();
          if (extender == null) {
            LogUtils.error(factory.getConfigurationElement(), "Cannot create extender");
            continue;
          }

          try {
            if (!extender.isEnabled(vb)) {
              continue;
            }
            extender.updateSourceProviderState(vb, context);
          } catch (final Exception ex) {
            LogUtils.error(factory.getConfigurationElement(), ex);
          }
        }
      }

      observe(event, values);
    } catch (final Exception ex) {
      LogUtils.error(this, ex);
    }
    return map;
  }
/**
 * Source Provider for the UI Binding framework.
 *
 * <p>As a side effect this source provider also activates/deactivates UI contexts - see {@link
 * Constants#CONTAINER_CONTEXT_ID} and {@link Constants#WIDGET_CONTEXT_ID}.
 *
 * <p>This class has a number of interfaces:
 *
 * <dl>
 *   <dt>{@link AbstractSourceProvider}
 *   <dd>Used by the expression framework.
 *   <dt>{@link BindingSourceProvider#getCurrentState(Event)}
 *   <dd>Calculates a new state based on the event, but it does <em>not</em> alter the global state.
 *   <dt>{@link BindingSourceProvider#reportSourceChanges(Event)}
 *   <dd>Calculates a new state based on the event, <em>and</em> alters the global state.
 * </dl>
 *
 * The provider uses a number of SWT events and if the current focus control is a {@link Table} or
 * {@link Tree}, it also monitors the current selection.
 *
 * @author Tonny Madsen, The RCP Company
 */
public class BindingSourceProvider extends AbstractSourceProvider {

  /**
   * The names of the sources supported by this source provider.
   *
   * <p><b>NOTE:</b> If you update this list, remember to update the services extension as well!
   * This is tested!!!
   */
  public static final String[] PROVIDED_SOURCE_NAMES =
      new String[] {
        Constants.SOURCES_THE_MANAGER,
        Constants.SOURCES_ACTIVE_CONTEXT,
        Constants.SOURCES_ACTIVE_BINDING,
        Constants.SOURCES_ACTIVE_BINDING_TYPE,
        Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT,
        Constants.SOURCES_ACTIVE_BINDING_FEATURE,
        Constants.SOURCES_ACTIVE_BINDING_RO,
        Constants.SOURCES_ACTIVE_BINDING_UNSETTABLE,
        Constants.SOURCES_ACTIVE_BINDING_OPEN_COMMAND,
        Constants.SOURCES_ACTIVE_BINDING_VALUE,
        Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY,
        Constants.SOURCES_ACTIVE_CONTAINER_BINDING,
        Constants.SOURCES_ACTIVE_CONTAINER_BINDING_NO_CAF,
        Constants.SOURCES_ACTIVE_CONTAINER_CELL_TYPE,
        Constants.SOURCES_ACTIVE_VIEWER_ELEMENT,
        Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_TYPE,
        Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_MOVE_UP,
        Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_MOVE_DOWN,
      };

  /** Constructs and returns a new source provider. */
  public BindingSourceProvider() {
    Display.getCurrent().addFilter(SWT.FocusIn, myDisplayFilter);
    Display.getCurrent().addFilter(SWT.MouseDown, myDisplayFilter);
    Display.getCurrent().addFilter(SWT.KeyUp, myDisplayFilter);
    Display.getCurrent().addFilter(SWT.MenuDetect, myDisplayFilter);

    resetMap(myCurrentState);
  }

  @Override
  public void dispose() {
    Display.getCurrent().removeFilter(SWT.FocusIn, myDisplayFilter);
    Display.getCurrent().removeFilter(SWT.MouseDown, myDisplayFilter);
    Display.getCurrent().removeFilter(SWT.KeyUp, myDisplayFilter);
    Display.getCurrent().removeFilter(SWT.MenuDetect, myDisplayFilter);
  }

  /** The manager itself. */
  private final IManager theManager = IManager.Factory.getManager();

  /**
   * Internal filter for the display used to track the current binding information.
   *
   * <p>Please be extremely careful in this code to be fast and bail out as quickly as possible.
   */
  private final Listener myDisplayFilter =
      new Listener() {
        @Override
        public void handleEvent(Event event) {
          reportSourceChanges(event);
        }
      };

  /** The previous state reported by the provider. */
  private final Map<String, Object> myCurrentState = new HashMap<String, Object>();

  /** The last widget that was used for {@link #getCurrentState(Event)}. */
  private Widget myLastWidget = null;

  /**
   * The current selection provider.
   *
   * <p>Changes in the selection prompts for a re-calculation of the sources.
   */
  protected ISelectionProvider myCurrentSelectionProvider = null;

  /** The listener used for {@link #myCurrentSelectionProvider}. */
  protected ISelectionChangedListener myCurrentSelectionProviderListener =
      new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
          if (Activator.getDefault().TRACE_SOURCE_PROVIDER_VERBOSE) {
            LogUtils.debug(this, "new selection: " + event.getSelection());
            if (event.getSelection().isEmpty()) {
              LogUtils.debug(this, "empty");
            }
          }
          reportSourceChanges(myPreviousValueEvent);
        }
      };

  /**
   * The UI Context service.
   *
   * <p>TODO: the the context service via the current IBindingContext
   */
  private final IContextService myContextService =
      (IContextService) PlatformUI.getWorkbench().getService(IContextService.class);

  /**
   * The last observable value that has been observed...
   *
   * <p>When/if the value changes, the state is recalculated...
   *
   * @see #observe(Event, List)
   */
  private final List<IObservableValue> myPreviousValues = new ArrayList<IObservableValue>();

  /** The event associated with {@link #myPreviousValues}. */
  private Event myPreviousValueEvent;

  /** A listener that monitors changes in {@link #myPreviousValues}. */
  private final IChangeListener myObservedChangeListener =
      new IChangeListener() {
        @Override
        public void handleChange(ChangeEvent event) {
          reportSourceChanges(myPreviousValueEvent);
        }
      };

  private IContextActivation myBaseContextContextActivation;

  private IContextActivation myWidgetContextContextActivation;

  private IContextActivation myContainerContextContextActivation;

  private IBinding myLastBinding;

  /**
   * Observes changes in the specified valuse with the associated event.
   *
   * @param event the event
   * @param newValues the observable values
   */
  protected void observe(Event event, List<IObservableValue> newValues) {
    myPreviousValueEvent = event;
    if (newValues.equals(myPreviousValues)) return;

    for (final IObservableValue v : myPreviousValues) {
      v.removeChangeListener(myObservedChangeListener);
    }
    myPreviousValues.clear();
    for (final IObservableValue v : newValues) {
      v.addChangeListener(myObservedChangeListener);
    }
    myPreviousValues.addAll(newValues);
  }

  /**
   * Checks if the current state have changed, and reports these.
   *
   * @param event the current event
   * @return the resulting map
   */
  public Map<String, Object> reportSourceChanges(Event event) {
    if (Activator.getDefault().TRACE_SOURCE_PROVIDER_VERBOSE
        && Activator.getDefault().TRACE_EVENTS_SWT) {
      LogUtils.debug(
          this, (event == myPreviousValueEvent ? "REPLAY " : "") + TSSWTUtils.toString(event));
    }

    /*
     * If the event is FocusIn for the very same widget as last time, but with x,y=0,0, then...
     * ignore it... It is seen whenever the current shell is send to front.
     */
    if (event.type == SWT.FocusIn && event.widget == myLastWidget && event.x == 0 && event.y == 0)
      return myCurrentState;

    /*
     * Ignore all key up events, except those that navigate...
     */
    // if (event.type == SWT.KeyUp && (SWT.KEYCODE_BIT & event.keyCode) == 0) {
    // return myOldState;
    // }

    final Map<String, Object> newState = getCurrentState(event);
    myLastWidget = event.widget;

    /*
     * Update the current state with changes - keeping them in newState as well.
     */
    for (final Iterator<Map.Entry<String, Object>> is = newState.entrySet().iterator();
        is.hasNext(); ) {
      final Map.Entry<String, Object> i = is.next();
      final String s = i.getKey();
      final Object n = i.getValue();

      final Object o = myCurrentState.get(s);
      if (BasicUtils.equals(n, o)) {
        is.remove();
      } else {
        myCurrentState.put(s, n);
      }
    }

    if (!newState.isEmpty()) {
      /*
       * Reset the property testers as well, when any of the values changes
       */
      newState.put(Constants.PREFIX + Constants.PROPERTY_CAN_DELETE, true);
      newState.put(Constants.PREFIX + Constants.PROPERTY_CAN_DELETE_SELECTED_OBJECTS, true);

      if (Activator.getDefault().TRACE_SOURCE_PROVIDER) {
        final StringBuilder sb = new StringBuilder("Binding sources change(" + myLastBinding + ")");
        for (final Map.Entry<String, Object> i : newState.entrySet()) {
          final String s = i.getKey();
          sb.append("\n  ").append(s).append('=');
          final Object v = i.getValue();
          if (v == null) {
            sb.append("<null>");
          } else if (v == IEvaluationContext.UNDEFINED_VARIABLE) {
            sb.append("<undef>");
          } else {
            sb.append('\'')
                .append(v.toString())
                .append('\'')
                .append(" [")
                .append(ClassUtils.getLastClassName(v))
                .append(']');
          }
        }
        LogUtils.debug(this, sb.toString());
      }

      fireSourceChanged(ISources.ACTIVE_CURRENT_SELECTION, newState);

      /*
       * TODO: describe why
       *
       * TODO: only when changing?
       */
      final Object activeBindingObject = myCurrentState.get(Constants.SOURCES_ACTIVE_BINDING);
      if (activeBindingObject instanceof IValueBinding) {
        final IValueBinding vb = (IValueBinding) activeBindingObject;
        IManagerRunnable.Factory.asyncExec(
            "update",
            vb,
            new Runnable() {
              @Override
              public void run() {
                if (vb.isDisposed()) return;
                vb.updateBinding();
              }
            });
      }

      /*
       * And lastly, update the active contexts
       */
      handleContextChanges(myCurrentState);
    }

    return myCurrentState;
  }

  /** @param newState */
  private void handleContextChanges(final Map<String, Object> newState) {
    /*
     * If inside a container binding, then activate the proper context
     */
    final boolean cb =
        newState.get(Constants.SOURCES_ACTIVE_CONTAINER_BINDING)
            != IEvaluationContext.UNDEFINED_VARIABLE;
    if (cb && myContainerContextContextActivation == null) {
      myContainerContextContextActivation =
          myContextService.activateContext(Constants.CONTAINER_CONTEXT_ID);
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "activated " + Constants.CONTAINER_CONTEXT_ID);
      }
    }
    if (!cb && myContainerContextContextActivation != null) {
      myContextService.deactivateContext(myContainerContextContextActivation);
      myContainerContextContextActivation = null;
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "deactivated " + Constants.CONTAINER_CONTEXT_ID);
      }
    }

    /*
     * If inside an value binding, then activate the proper context
     */
    final boolean vb =
        !cb
            && newState.get(Constants.SOURCES_ACTIVE_BINDING)
                != IEvaluationContext.UNDEFINED_VARIABLE;
    if (vb && myWidgetContextContextActivation == null) {
      myWidgetContextContextActivation =
          myContextService.activateContext(Constants.WIDGET_CONTEXT_ID);
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "activated " + Constants.WIDGET_CONTEXT_ID);
      }
    }
    if (!vb && myWidgetContextContextActivation != null) {
      myContextService.deactivateContext(myWidgetContextContextActivation);
      myWidgetContextContextActivation = null;
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "deactivated " + Constants.WIDGET_CONTEXT_ID);
      }
    }

    /*
     * Also activate the base context - this does not seem to happen automatically ???
     */
    final boolean bc =
        myContainerContextContextActivation != null || myWidgetContextContextActivation != null;
    if (bc && myBaseContextContextActivation == null) {
      myBaseContextContextActivation =
          myContextService.activateContext(Constants.COMMON_CONTEXT_ID);
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "activated " + Constants.COMMON_CONTEXT_ID);
      }
    }
    if (!bc && myBaseContextContextActivation != null) {
      myContextService.deactivateContext(myBaseContextContextActivation);
      myBaseContextContextActivation = null;
      if (Activator.getDefault().TRACE_CONTEXTS) {
        LogUtils.debug(this, "deactivated " + Constants.COMMON_CONTEXT_ID);
      }
    }
  }

  @Override
  public Map<String, Object> getCurrentState() {
    return myCurrentState;
  }

  /**
   * Returns a Map with the current state for the specific event if specified.
   *
   * @param event the current event - possibly <code>null</code>
   * @return a Map with the current state
   */
  public Map<String, Object> getCurrentState(final Event event) {
    final Map<String, Object> map = new HashMap<String, Object>();
    final List<IObservableValue> values = new ArrayList<IObservableValue>();
    resetMap(map);
    if (event.type == SWT.MenuDetect) {
      // LogUtils.debug(event, "MenuDetect");
    }
    try {
      myLastBinding = IBindingContext.Factory.getBindingForWidget(event.widget);
      if (myLastBinding == null) return map;

      map.put(Constants.SOURCES_ACTIVE_CONTEXT, myLastBinding.getContext());

      final ISourceProviderStateContext context =
          new ISourceProviderStateContext() {
            @Override
            public Event getEvent() {
              return event;
            }

            private Point myLocation = null;

            @Override
            public Point getLocation() {
              if (myLocation == null) {
                myLocation = new Point(event.x, event.y);
                switch (event.type) {
                  case SWT.MenuDetect:
                    /*
                     * The location is relative to the display
                     */
                    myLocation =
                        event.widget.getDisplay().map(null, (Control) event.widget, myLocation);
                    break;
                  default:
                    break;
                }
              }
              return myLocation;
            }

            @Override
            public Map<String, Object> getState() {
              return map;
            }

            @Override
            public void putSourceValue(String name, Object value) {
              map.put(name, value);
            }

            @Override
            public void addObservedValue(IObservableValue value) {
              values.add(value);
            }

            @Override
            public void setSelectionProvider(ISelectionProvider provider) {
              if (provider == myCurrentSelectionProvider) return;
              if (myCurrentSelectionProvider != null) {
                myCurrentSelectionProvider.removeSelectionChangedListener(
                    myCurrentSelectionProviderListener);
              }
              myCurrentSelectionProvider = provider;
              if (myCurrentSelectionProvider != null) {
                myCurrentSelectionProvider.addSelectionChangedListener(
                    myCurrentSelectionProviderListener);
              }
            }
          };
      try {
        myLastBinding.updateSourceProviderState(context);
      } catch (final Exception ex) {
        LogUtils.error(myLastBinding, ex);
      }

      /*
       * If the active binding is a value binding, run all extenders as well...
       */
      final Object activeBinding = map.get(Constants.SOURCES_ACTIVE_BINDING);
      if (activeBinding instanceof IValueBinding) {
        final IValueBinding vb = (IValueBinding) activeBinding;
        for (final IUIBindingDecoratorExtenderDescriptor d :
            IManager.Factory.getManager().getDecoratorExtenders()) {
          final CEObjectHolder<IUIBindingDecoratorExtender> factory = d.getFactory();
          final IUIBindingDecoratorExtender extender = factory.getObject();
          if (extender == null) {
            LogUtils.error(factory.getConfigurationElement(), "Cannot create extender");
            continue;
          }

          try {
            if (!extender.isEnabled(vb)) {
              continue;
            }
            extender.updateSourceProviderState(vb, context);
          } catch (final Exception ex) {
            LogUtils.error(factory.getConfigurationElement(), ex);
          }
        }
      }

      observe(event, values);
    } catch (final Exception ex) {
      LogUtils.error(this, ex);
    }
    return map;
  }

  private void resetMap(final Map<String, Object> map) {
    map.put(Constants.SOURCES_THE_MANAGER, theManager);
    map.put(Constants.SOURCES_ACTIVE_CONTEXT, IEvaluationContext.UNDEFINED_VARIABLE);

    map.put(Constants.SOURCES_ACTIVE_CONTAINER_BINDING, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_CONTAINER_CELL_TYPE, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_CONTAINER_BINDING_NO_CAF, false);

    map.put(Constants.SOURCES_ACTIVE_VIEWER_ELEMENT, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_TYPE, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_MOVE_UP, false);
    map.put(Constants.SOURCES_ACTIVE_VIEWER_ELEMENT_MOVE_DOWN, false);

    map.put(Constants.SOURCES_ACTIVE_BINDING, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_BINDING_TYPE, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_BINDING_MODEL_OBJECT, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_BINDING_FEATURE, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_BINDING_RO, true);
    map.put(Constants.SOURCES_ACTIVE_BINDING_UNSETTABLE, false);
    map.put(Constants.SOURCES_ACTIVE_BINDING_OPEN_COMMAND, IEvaluationContext.UNDEFINED_VARIABLE);

    map.put(Constants.SOURCES_ACTIVE_BINDING_VALUE, IEvaluationContext.UNDEFINED_VARIABLE);
    map.put(Constants.SOURCES_ACTIVE_BINDING_VALUE_DISPLAY, IEvaluationContext.UNDEFINED_VARIABLE);
  }

  @Override
  public String[] getProvidedSourceNames() {
    return PROVIDED_SOURCE_NAMES;
  }
}
  @Override
  protected void createFieldEditors() {
    final INavigatorManager manager = INavigatorManager.Factory.getManager();
    FieldEditor editor;

    final IManager uim = IManager.Factory.getManager();
    for (final CEObjectHolder<EObject> pmt : manager.getPreferenceModelTypes()) {
      final IEditorInformation mt = manager.getEditorInformation(pmt.getObjectClass());

      final String[][] translation = new String[mt.getEditors().size()][];
      for (int i = 0; i < translation.length; i++) {
        final IEditorPartDescriptor d = mt.getEditors().get(i);
        translation[i] = new String[] {d.getName(), d.getId()};
      }

      // IBindingObjectInformation.Factory.getLabel(mt.g) - upps - no class yet, just a name
      /*
       * TODO: change this to use a proper binding
       *
       * IBindingObjectInformation
       */
      String n = mt.getModelType();
      if (n.lastIndexOf('.') != -1) {
        n = n.substring(n.lastIndexOf('.') + 1);
      }
      if (n.matches("^I[A-Z]")) {
        n = n.substring(1);
      }
      String name = ToStringUtils.formatHumanReadable(n);
      final IModelClassInfo info = uim.getModelClassInfo(mt.getModelType(), null, false);
      if (info != null) {
        final Object l = info.getArguments().get(Constants.ARG_LABEL);
        if (l != null && l instanceof String) {
          name = (String) l;
        }
      }
      editor = new ComboFieldEditor(mt.getModelType(), name, translation, getFieldEditorParent());

      addField(editor);
    }

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_USE_GENERIC_EDITOR_PART_FALLBACK,
            "Fall back on generic editor part",
            getFieldEditorParent());
    addField(editor);

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_OPEN_MUST_OPEN_NEW,
            "Open command should open new editors",
            getFieldEditorParent());
    addField(editor);

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_SHOW_PIN_EDITOR_CONTRIBUTION,
            "Show 'pin editor' contribution in menus and toolbars",
            getFieldEditorParent());
    addField(editor);

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_PIN_EDITOR_BY_DEFAULT,
            "Pin new editors by default",
            getFieldEditorParent());
    addField(editor);

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_SHOW_CLONE_EDITOR_CONTRIBUTION,
            "Show 'clone editor' contribution in menus and toolbars",
            getFieldEditorParent());
    addField(editor);

    editor =
        new BooleanFieldEditor(
            NavigatorConstants.PREF_SHOW_CLONE_EDITOR_CONTRIBUTION,
            "Show other contribution in menus and toolbars",
            getFieldEditorParent());
    addField(editor);
  }
 @After
 public void after() {
   IManager.Factory.getManager().setEditCellSingleClick(true);
 }