Tuesday, October 2, 2007

Custom Property Source for EMF generated RCP application

Have you ever tried to generate your application using EMF? If yes, you have probably noticed, that EMF puts standard editors for properties. For testing purposes this is enough, but for commercial application... well... answer yourself.

In this post I will show you how to generate simple date editor for the EMF application.
Here is the model:


As you see, it is not very complicated. If we generate RCP appliaction we will receive something like that:


and additional three plugins in your workspace (.edit, .editor, and .tests).

So we start to work.

In the pluging .editor we open our application Editor, and then, in the method getPropertySheetPage() we replace the

propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory));

with

propertySheetPage.setPropertySourceProvider(new CustomizedAdapterFactoryContentProvider(adapterFactory));

Such a class does not exists, so we have to create it (it should extend AdapterFactoryContentProvider) and override method createPropertySource:


protected IPropertySource createPropertySource(Object object,
 IItemPropertySource itemPropertySource) {
            return new CustomizedPropertySource(object, itemPropertySource);
}


We do not have CustomizedPropertySource yet, so we create one, and override
createPropertyDescriptor() method:

protected IPropertyDescriptor createPropertyDescriptor(
IItemPropertyDescriptor itemPropertyDescriptor) {
      return new CustomizedPropertyDescriptor(object, itemPropertyDescriptor);
}


We do not have one. We have to create it and override createPropertyEditor, finally;):

public CellEditor createPropertyEditor(Composite composite) {
   CellEditor result = super.createPropertyEditor(composite);
   if(result == null) return result;
   EClassifier eType =         ((EStructuralFeature)itemPropertyDescriptor.getFeature(object)).getEType();
   if (eType instanceof EDataType) {
      EDataType eDataType = (EDataType) eType;
      if(eDataType.getInstanceClass() == Date.class){
         result = new ExtendedDialogCellEditor(composite, getEditLabelProvider()){
             protected Object openDialogBox(Control cellEditorWindow) {
                final DateTime dateTime[] = new DateTime[1];
                final Date[] date = new Date[1];
                Dialog d = new Dialog(cellEditorWindow.getShell()){
                   protected Control createDialogArea(Composite parent) {
                      Composite dialogArea = (Composite) super.createDialogArea(parent);
                      dateTime[0] = new DateTime(dialogArea, SWT.CALENDAR);
                      dateTime[0].addSelectionListener(new SelectionAdapter(){
                          public void widgetSelected(SelectionEvent e) {
                              Date dateValue = new Date();
                              dateValue.setYear(dateTime[0].getYear());
                              dateValue.setMonth(dateTime[0].getMonth());
                              dateValue.setDate(dateTime[0].getDay());
                              date[0] = dateValue;
                              super.widgetSelected(e);
                           }
                      });
                      return dialogArea;
                   }
                };
               d.setBlockOnOpen(true);
               d.open();
               if(d.getReturnCode() == Dialog.OK){
                  return date[0];
               }
               return null;
            }
         };
      }
   }
   return result;
}


In this method we provide date property editor, but also we have to check, if the property is editable and if it is really a date, because our method will take care about all properties. So, if this is not a date, we pass everything to the super implementation.

And voila :) Here it is:




So, to sum up: you modify your editor to use subclassed AdapterFactoryContentProvider that will return subclassed PropertySource that will return subclassed PropertyDescriptor that will create your desired cell editor.

Hope that will help you :).

4 comments:

Ed Merks said...

This is cool! If you would open an EMF bugzilla enhancement request with this example I will do this in the base framework.

vishnu said...

hi
can u explain how the samething can be done in a dialog box rather than in an editor.

Chandresh said...

Hi,

can you please tell, whether this approach is even usefull for getting custom properties (upon selection in other view) from model designed in EMF ?

mark le said...

This is really helpful. I didn't have the same issue but I used your approach to implement a similar feature. Good job!