]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java
Allow repeated single clicks to activate property editing
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / property / AnnotatedPropertyTabContributorFactory.java
index a3fca78bb4206dc18adafa617073919702042778..344dd8cabc1be4805f46f07d46d3025252b880a7 100644 (file)
@@ -18,6 +18,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -38,6 +39,7 @@ import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
 import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener;
 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
 import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
 import org.eclipse.jface.viewers.EditingSupport;
 import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
 import org.eclipse.jface.viewers.ISelection;
@@ -68,10 +70,12 @@ import org.eclipse.ui.IWorkbenchSite;
 import org.simantics.db.management.ISessionContext;
 import org.simantics.g3d.property.annotations.CompoundGetPropertyValue;
 import org.simantics.g3d.property.annotations.CompoundSetPropertyValue;
+import org.simantics.g3d.property.annotations.GetComboProperty;
+import org.simantics.g3d.property.annotations.GetComboPropertyValue;
 import org.simantics.g3d.property.annotations.GetPropertyValue;
 import org.simantics.g3d.property.annotations.PropertyTabBlacklist;
+import org.simantics.g3d.property.annotations.SetComboPropertyValue;
 import org.simantics.g3d.property.annotations.SetPropertyValue;
-import org.simantics.g3d.scenegraph.IG3DNode;
 import org.simantics.g3d.scenegraph.NodeMap;
 import org.simantics.g3d.scenegraph.NodeMapProvider;
 import org.simantics.g3d.scenegraph.base.INode;
@@ -81,7 +85,6 @@ import org.simantics.g3d.scenegraph.structural.IStructuralNode;
 import org.simantics.g3d.tools.AdaptationUtils;
 import org.simantics.selectionview.IPropertyTab;
 import org.simantics.selectionview.IPropertyTab2;
-import org.simantics.utils.datastructures.Callback;
 import org.simantics.utils.datastructures.MapList;
 
 public class AnnotatedPropertyTabContributorFactory implements PropertyTabContributorFactory {
@@ -131,91 +134,121 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
        
        
        private static void collectItems(Class<?> clazz, Map<String, IPropertyItem> items) throws InstantiationException, IllegalAccessException {
-                Class<?> superclass = clazz.getSuperclass();
-                if(superclass != null)
-                        collectItems(superclass, items);
-                
-                for (Method m : clazz.getDeclaredMethods()) {
-                        m.setAccessible(true);
-               for (Annotation annotation : m.getAnnotations()) {
-                       if (annotation.annotationType().equals(GetPropertyValue.class)) {
-                               GetPropertyValue get = (GetPropertyValue)annotation;
-                               PropertyItem item = (PropertyItem)items.get(get.value());
-                               if (item == null) {
-                                       item = new PropertyItem(get.value());
-                                       items.put(item.id, item);
-                               }
+               Class<?> superclass = clazz.getSuperclass();
+               if(superclass != null)
+                       collectItems(superclass, items);
+               
+               for (Method m : clazz.getDeclaredMethods()) {
+                       m.setAccessible(true);
+                       for (Annotation annotation : m.getAnnotations()) {
+                               if (annotation.annotationType().equals(GetPropertyValue.class)) {
+                                       GetPropertyValue get = (GetPropertyValue)annotation;
+                                       PropertyItem item = (PropertyItem)items.get(get.value());
+                                       if (item == null) {
+                                               item = new PropertyItem(get.value());
+                                               items.put(item.id, item);
+                                       }
+
+                                       item.getter = m;
+                                       item.manipulatorClass = get.manipulator().newInstance().get(m,null);
+
+                                       item.tabId = get.tabId();
 
-                               item.getter = m;
-                               item.manipulatorClass = get.manipulator().newInstance().get(m,null);
+                                       item.name = get.name();
+                                       
+                                       
+                               } else if (annotation.annotationType().equals(SetPropertyValue.class)) {
+                                       SetPropertyValue set = (SetPropertyValue)annotation;
+                                       PropertyItem item = (PropertyItem)items.get(set.value());
+                                       if (item == null) {
+                                               item = new PropertyItem(set.value());
+                                               items.put(item.id, item);
+                                       }
+                                       
+                                       item.setter = m;
+                               } else if (annotation.annotationType().equals(CompoundGetPropertyValue.class)) {
+                                       CompoundGetPropertyValue get = (CompoundGetPropertyValue)annotation;
+                                       CompoundPropertyItem item = (CompoundPropertyItem)items.get(get.value());
+                                       if (item == null) {
+                                               item = new CompoundPropertyItem(get.value());
+                                               items.put(item.id, item);
+                                       }
 
-                               item.tabId = get.tabId();
+                                       item.getter = m;
+                                       item.manipulatorFactory = get.manipulator().newInstance();
 
-                               item.name = get.name();
-                               
-                               
-                       } else if (annotation.annotationType().equals(SetPropertyValue.class)) {
-                               SetPropertyValue set = (SetPropertyValue)annotation;
-                               PropertyItem item = (PropertyItem)items.get(set.value());
-                               if (item == null) {
-                                       item = new PropertyItem(set.value());
-                                       items.put(item.id, item);
-                               }
-                               
-                               item.setter = m;
-                       } else if (annotation.annotationType().equals(CompoundGetPropertyValue.class)) {
-                               CompoundGetPropertyValue get = (CompoundGetPropertyValue)annotation;
-                               CompoundPropertyItem item = (CompoundPropertyItem)items.get(get.value());
-                               if (item == null) {
-                                       item = new CompoundPropertyItem(get.value());
-                                       items.put(item.id, item);
-                               }
+                                       item.tabId = get.tabId();
 
-                               item.getter = m;
-                               item.manipulatorFactory = get.manipulator().newInstance();
+                                       item.name = get.name();
+                               } else if (annotation.annotationType().equals(CompoundSetPropertyValue.class)) {
+                                       CompoundSetPropertyValue set = (CompoundSetPropertyValue)annotation;
+                                       CompoundPropertyItem item = (CompoundPropertyItem)items.get(set.value());
+                                       if (item == null) {
+                                               item = new CompoundPropertyItem(set.value());
+                                               items.put(item.id, item);
+                                       }
+                                       
+                                       item.setter = m;
+                               } else if (annotation.annotationType().equals(GetComboPropertyValue.class)) {
+                                   GetComboPropertyValue get = (GetComboPropertyValue)annotation;
+                                   ComboPropertyItem item = (ComboPropertyItem)items.get(get.value());
+                    if (item == null) {
+                        item = new ComboPropertyItem(get.value());
+                        items.put(item.id, item);
+                    }
+                    item.getter = m;
+                    item.manipulatorClass = ComboPropertyManipulator.class;
 
-                               item.tabId = get.tabId();
+                    item.tabId = get.tabId();
 
-                               item.name = get.name();
-                       } else if (annotation.annotationType().equals(CompoundSetPropertyValue.class)) {
-                               CompoundSetPropertyValue set = (CompoundSetPropertyValue)annotation;
-                               CompoundPropertyItem item = (CompoundPropertyItem)items.get(set.value());
-                               if (item == null) {
-                                       item = new CompoundPropertyItem(set.value());
-                                       items.put(item.id, item);
-                               }
-                               
-                               item.setter = m;
-                       }
-               }
-                }
+                    item.name = get.name();
+                               } else if (annotation.annotationType().equals(SetComboPropertyValue.class)) {
+                                   SetComboPropertyValue set = (SetComboPropertyValue)annotation;
+                    ComboPropertyItem item = (ComboPropertyItem)items.get(set.value());
+                    if (item == null) {
+                        item = new ComboPropertyItem(set.value());
+                        items.put(item.id, item);
+                    }
+                    item.setter = m;
+                               } else if (annotation.annotationType().equals(GetComboProperty.class)) {
+                                   GetComboProperty get = (GetComboProperty)annotation;
+                    ComboPropertyItem item = (ComboPropertyItem)items.get(get.value());
+                    if (item == null) {
+                        item = new ComboPropertyItem(get.value());
+                        items.put(item.id, item);
+                    }
+                    item.values = m;
+                               }
+                       }
+               }
                
                
        }
        
        private static void collectBlacklist(Class<?> clazz, List<String> blacklist) throws InstantiationException, IllegalAccessException {
-                Class<?> superclass = clazz.getSuperclass();
-                if(superclass != null)
-                        collectBlacklist(superclass, blacklist);
-                
-                PropertyTabBlacklist ann = clazz.getAnnotation(PropertyTabBlacklist.class);
-                if (ann == null)
-                        return;
-                String s = ann.value();
-                if (s == null)
-                        return;
-                if (s.length() == 0)
-                        return;
-                for (String item : s.split(";")) {
-                        blacklist.add(item);
-                }
-                
+               Class<?> superclass = clazz.getSuperclass();
+               if(superclass != null)
+                       collectBlacklist(superclass, blacklist);
+               
+               PropertyTabBlacklist ann = clazz.getAnnotation(PropertyTabBlacklist.class);
+               if (ann == null)
+                       return;
+               String s = ann.value();
+               if (s == null)
+                       return;
+               if (s.length() == 0)
+                       return;
+               for (String item : s.split(";")) {
+                       blacklist.add(item);
+               }
+               
                
        }
        
        private static Map<PropertyItem, PropertyManipulator> createManipulators(CompoundPropertyItem item, Object obj) {
                try {
                        
+                       @SuppressWarnings("unchecked")
                        Map<String,Object> map = (Map<String, Object>)item.getter.invoke(obj);
                        Map<PropertyItem, PropertyManipulator> result = new HashMap<AnnotatedPropertyTabContributorFactory.PropertyItem, PropertyManipulator>();
                        for (String key : map.keySet()) {
@@ -232,7 +265,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        return result;
                } catch (Exception e) {
                        e.printStackTrace();
-                       return Collections.EMPTY_MAP;
+                       return Collections.emptyMap();
                } 
                
        }
@@ -248,8 +281,22 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                } 
        }
        
+       private static PropertyManipulator createManipulator(ComboPropertyItem item, Object obj) {
+        try {
+            MethodComboValueProvider provider = new MethodComboValueProvider(item.getter, item.setter,item.values);
+            PropertyManipulator manipulator = item.manipulatorClass.getConstructor(ValueProvider.class,Object.class).newInstance(provider,obj);
+            return manipulator;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        } 
+    }
+       
        private static interface IPropertyItem {
                public String getTabId();
+               public String getName();
+               public String getId();
+               public boolean editable();
        }
        
        private static class PropertyItem implements IPropertyItem{
@@ -267,6 +314,11 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        this.id = id;
                }
                
+               @Override
+               public String getId() {
+                   return id;
+               }
+               
                @Override
                public int hashCode() {
                        return id.hashCode();
@@ -276,6 +328,16 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                public String getTabId() {
                        return tabId;
                }
+               
+               @Override
+               public String getName() {
+                   return name;
+               }
+               
+               @Override
+               public boolean editable() {
+                   return setter != null;
+               }
        }
        
        private static class CompoundPropertyItem implements IPropertyItem{
@@ -293,6 +355,11 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        this.id = id;
                }
                
+               @Override
+        public String getId() {
+            return id;
+        }
+               
                @Override
                public int hashCode() {
                        return id.hashCode();
@@ -302,8 +369,60 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                public String getTabId() {
                        return tabId;
                }
+               
+               @Override
+        public String getName() {
+            return name;
+        }
+               
+               @Override
+        public boolean editable() {
+            return setter != null;
+        }
        }
        
+       private static class ComboPropertyItem implements IPropertyItem{
+        private String id;
+        private String name;
+        private String tabId;
+        private Method getter;
+        private Method setter;
+        private Method values;
+        private Class<? extends ComboPropertyManipulator> manipulatorClass;
+        
+        
+        public ComboPropertyItem(String id) {
+            if (id == null)
+                throw new NullPointerException();
+            this.id = id;
+        }
+        
+        @Override
+        public String getId() {
+            return id;
+        }
+        
+        @Override
+        public int hashCode() {
+            return id.hashCode();
+        }
+        
+        @Override
+        public String getTabId() {
+            return tabId;
+        }
+        
+        @Override
+        public String getName() {
+            return name;
+        }
+        
+        @Override
+        public boolean editable() {
+            return setter != null;
+        }
+    }
+       
        private static class AnnotatedPropertyTabContributor implements PropertyTabContributor {
                private String id; 
                List<IPropertyItem> items;
@@ -333,13 +452,13 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
        private static class AnnotatedPropertyTab implements IPropertyTab2, NodeListener {
                //private String id; 
                List<IPropertyItem> contibutedItems;
-               List<PropertyItem> resolvedItems = new ArrayList<PropertyItem>();
-               private Map<PropertyItem,PropertyManipulator> manipulators = new HashMap<PropertyItem, PropertyManipulator>();
+               List<IPropertyItem> resolvedItems = new ArrayList<IPropertyItem>();
+               private Map<IPropertyItem,PropertyManipulator> manipulators = new HashMap<IPropertyItem, PropertyManipulator>();
                
                private TableViewer viewer;
                
-               private IG3DNode node;
-               private NodeMap<?,?> nodeMap;
+               private INode node;
+               private NodeMap<?,?,?> nodeMap;
                
                private List<TableViewerColumn> valueColumns = new ArrayList<TableViewerColumn>();
                
@@ -389,34 +508,13 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                }
                        });
                        
-                       int valueCount = 0;
-                       for (IPropertyItem item : contibutedItems) {
-                               if (item instanceof PropertyItem) {
-                                       PropertyManipulator manipulator = createManipulator((PropertyItem)item, null);
-                                       if (manipulator == null)
-                                               continue;
-                                       if (valueCount < manipulator.getValueCount())
-                                               valueCount = manipulator.getValueCount();
-                               } else if (item instanceof CompoundPropertyItem) {
-                                       if (valueCount < 1)
-                                               valueCount = 1;
-                               }
-                       }
-                       for (int i = 0; i < valueCount; i++) {
-                               TableViewerColumn value = new TableViewerColumn(viewer, SWT.LEFT);
-                               //value.getColumn().setText("Value " + (i+1));
-                               value.getColumn().setText("");
-                               value.getColumn().setWidth(200);
-                               valueColumns.add(value);
-                               //value.setEditingSupport(new )
-                       }
                        viewer.getTable().setHeaderVisible(true);
                        viewer.getTable().setLinesVisible(true);
                        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
                                
                                @Override
                                public void selectionChanged(SelectionChangedEvent event) {
-                                       PropertyItem item = AdaptationUtils.adaptToSingle(event.getSelection(), PropertyItem.class);
+                                       IPropertyItem item = AdaptationUtils.adaptToSingle(event.getSelection(), IPropertyItem.class);
                                        selectedItem = item;
                                        if (!manipulators.get(selectedItem).getEditMode())
                                                manipulators.get(selectedItem).setEditMode(true);
@@ -501,10 +599,22 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        }
                        ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
                                        viewer) {
+                               Object lastSource = null;
+                               int clickCount = 0;
+                               
                                protected boolean isEditorActivationEvent(
                                                ColumnViewerEditorActivationEvent event) {
+                                       if (!event.getSource().equals(lastSource))
+                                               clickCount = 0;
+                                       
+                                       lastSource = event.getSource();
+                                       
+                                       if (event.eventType == ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION)
+                                               clickCount += 1;
+                                               
                                        return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
                                                        || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
+                                                       || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION && clickCount >= 2
                                                        || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR)
                                                        || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
                                }
@@ -547,7 +657,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                @Override
                public void setInput(ISessionContext context, ISelection selection,
                                boolean force) {
-                       Collection<IG3DNode> nodes = AdaptationUtils.adaptToCollection(selection, IG3DNode.class);
+                       Collection<INode> nodes = AdaptationUtils.adaptToCollection(selection, INode.class);
                        if (nodes.size() != 1) {
                                if (node != null) {
                                        node.removeListener(this);
@@ -555,7 +665,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                }
                                return;
                        }
-                       IG3DNode n = nodes.iterator().next();
+                       INode n = nodes.iterator().next();
                        if (node != null) {
                                if (!node.equals(n)) {
                                        node.removeListener(this);
@@ -568,51 +678,76 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                
                
                
-               private void setInput(IG3DNode node) {
+               private void setInput(INode node) {
                        this.node = node;
                        this.node.addListener(this);
                        // resolve nodemap
-                       IG3DNode n = node;
+                       INode n = node;
                        while (true) {
                                if (n == null) {
                                        nodeMap = null;
                                        break;
                                }
-                               if (n instanceof NodeMapProvider<?,?>) {
-                                       nodeMap = ((NodeMapProvider<?,?>) n).getNodeMap();
+                               if (n instanceof NodeMapProvider<?,?,?>) {
+                                       nodeMap = ((NodeMapProvider<?,?,?>) n).getNodeMap();
                                        if (nodeMap != null)
                                                break;
                                }
-                               n = (IG3DNode)n.getParent();
+                               n = (INode)n.getParent();
                        }
                        boolean readOnly =  (node instanceof IStructuralNode && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot());
-                       // create label providers
-                       PropertyValueLabelProvider2 p = new PropertyValueLabelProvider2(this);
-                       int index = 0;
-                       for (TableViewerColumn c : valueColumns) {
-                               c.setLabelProvider(p);
-                               if (!readOnly) {
-                                       PropertyEditingSupport support = new PropertyEditingSupport(this, viewer, index++, nodeMap);
-                                       c.setEditingSupport(support);
-                               }
-                       }
+                       
                        resolvedItems.clear();
                        manipulators.clear();
                        for (IPropertyItem item : contibutedItems) {
                                if (item instanceof PropertyItem) {
                                        resolvedItems.add((PropertyItem)item);
                                        manipulators.put((PropertyItem)item, createManipulator((PropertyItem)item, node));
-                               }
-                               else {
+                               } else if (item instanceof ComboPropertyItem) {
+                                   resolvedItems.add((ComboPropertyItem)item);
+                                   manipulators.put((ComboPropertyItem)item, createManipulator((ComboPropertyItem)item, node));
+                               } else if (item instanceof CompoundPropertyItem) {
                                        CompoundPropertyItem compound = (CompoundPropertyItem)item;
                                        Map<PropertyItem, PropertyManipulator> manipulators = createManipulators(compound, node);
                                        for (PropertyItem i : manipulators.keySet()) {
                                                resolvedItems.add(i);
                                                this.manipulators.put(i, manipulators.get(i));
                                        }
+                               } else {
+                                   
                                }
                        }
                        
+                       int valueCount = 0;
+                       for (PropertyManipulator manipulator : manipulators.values()) {
+                           if (valueCount < manipulator.getValueCount())
+                   valueCount = manipulator.getValueCount();
+                       }
+            for (int i = 0; i < valueCount; i++) {
+                TableViewerColumn value = new TableViewerColumn(viewer, SWT.LEFT);
+                //value.getColumn().setText("Value " + (i+1));
+                value.getColumn().setText("");
+                value.getColumn().setWidth(200);
+                valueColumns.add(value);
+                //value.setEditingSupport(new )
+            }
+            
+            // create label providers
+            PropertyValueLabelProvider2 p = new PropertyValueLabelProvider2(this);
+            int index = 0;
+            for (TableViewerColumn c : valueColumns) {
+                c.setLabelProvider(p);
+                if (!readOnly) {
+                    PropertyEditingSupport support = new PropertyEditingSupport(this, viewer, index++, nodeMap);
+                    c.setEditingSupport(support);
+                }
+            }
+                       Collections.sort(resolvedItems, new Comparator<IPropertyItem>() {
+                           @Override
+                           public int compare(IPropertyItem o1, IPropertyItem o2) {
+                               return o1.getName().compareTo(o2.getName());
+                           }
+            });
                        viewer.getTable().setEnabled(!readOnly);
                        viewer.setInput(resolvedItems);
                }
@@ -676,7 +811,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                if (viewer.getTable().isDisposed())
                                        return;
                                if (DEBUG)System.out.println("Viewer refresh " + id);
-                               for (PropertyItem item : resolvedItems)
+                               for (IPropertyItem item : resolvedItems)
                                        if (!item.equals(selectedItem))
                                                viewer.refresh(item);
                                if (selectedItem != null)
@@ -692,7 +827,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                                        return;
                                                }
                                                if (DEBUG) System.out.println("Viewer threaded refresh " + id);
-                                               for (PropertyItem item : resolvedItems)
+                                               for (IPropertyItem item : resolvedItems)
                                                        if (!item.equals(selectedItem))
                                                                viewer.refresh(item);
                                                if (selectedItem != null)
@@ -701,7 +836,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                        }
                                });
                        } else {
-                               for (PropertyItem item : resolvedItems) {
+                               for (IPropertyItem item : resolvedItems) {
                                        delayedUpdate.add(item);
                                }
                        }
@@ -717,7 +852,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        
                }
                
-               public PropertyManipulator getManipulator(PropertyItem item) {
+               public PropertyManipulator getManipulator(IPropertyItem item) {
                        return manipulators.get(item);
                }
                
@@ -733,11 +868,11 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
        private static class PropertyEditingSupport extends EditingSupport {
                AnnotatedPropertyTab tab;
                int index;
-               NodeMap<?,?> nodeMap;
+               NodeMap<?,?,?> nodeMap;
                TableViewer viewer;
                CellEditor editor;
 
-               public PropertyEditingSupport(AnnotatedPropertyTab tab, TableViewer viewer, int index, NodeMap<?,?> nodeMap) {
+               public PropertyEditingSupport(AnnotatedPropertyTab tab, TableViewer viewer, int index, NodeMap<?,?,?> nodeMap) {
                        super(viewer);
                        this.tab = tab;
                        this.index = index;
@@ -747,10 +882,10 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                
                @Override
                protected boolean canEdit(Object element) {
-                       PropertyItem item = (PropertyItem)element;
+                       IPropertyItem item = (IPropertyItem)element;
                        if (tab.getManipulator(item).getValueCount() <= index)
                                return false;
-                       if (item.setter == null)
+                       if (!item.editable())
                                return false;
                        if (getValue(element) == null)
                                return false;
@@ -759,32 +894,52 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                
                @Override
                protected CellEditor getCellEditor(Object element) {
-                       
-                       if (tab.getManipulator((PropertyItem)element).getValueCount() <= index)
+                       IPropertyItem item = (IPropertyItem)element;
+                       if (tab.getManipulator(item).getValueCount() <= index)
                                return null;
                        if (editor == null)
-                               editor = new TextCellEditor(viewer.getTable(),SWT.NONE) {
-                               @Override
-                               public void activate() {
-                                       tab.setEditing(true);
-                               }
-                               
-                               @Override
-                               public void deactivate() {
-                                       super.deactivate();
-                                       tab.setEditing(false);
-                               }
-                       };
+                           if (item instanceof PropertyItem)
+                               editor = new TextCellEditor(viewer.getTable(),SWT.NONE) {
+                               @Override
+                               public void activate() {
+                                       tab.setEditing(true);
+                               }
+                               
+                               @Override
+                               public void deactivate() {
+                                       super.deactivate();
+                                       tab.setEditing(false);
+                               }
+                       };
+                       else if (item instanceof ComboPropertyItem) {
+                           ComboPropertyItem comboPropertyItem = (ComboPropertyItem)item;
+                           ComboPropertyManipulator manipulator = (ComboPropertyManipulator)tab.manipulators.get(comboPropertyItem);
+                           editor = new ComboBoxCellEditor(viewer.getTable(), manipulator.getItems()) {
+                               @Override
+                        public void activate() {
+                            tab.setEditing(true);
+                        }
+                        
+                        @Override
+                        public void deactivate() {
+                            super.deactivate();
+                            tab.setEditing(false);
+                        }    
+                           };
+                       }
                        if (DEBUG)System.err.println("CELL EDITOR: " + element);
                        return editor;
                }
                
                @Override
                protected Object getValue(Object element) {
-                       PropertyItem item = (PropertyItem)element;
+                       IPropertyItem item = (IPropertyItem)element;
                        PropertyManipulator manipulator = tab.getManipulator(item);//createManipulator(item, obj);
                        if (manipulator.getValueCount() <= index)
                                return null;
+                       if (manipulator instanceof ComboPropertyManipulator) {
+                           return ((ComboPropertyManipulator)manipulator).getValueIndex();
+                       }
                        Object value = manipulator.getValue(index);
                        return value;
                }
@@ -792,14 +947,14 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                @Override
                protected void setValue(Object element, Object value) {
                        
-                       PropertyItem item = (PropertyItem)element;
+                       IPropertyItem item = (IPropertyItem)element;
                        PropertyManipulator manipulator = tab.getManipulator(item);//createManipulator(item, obj);
                        if (manipulator.getValueCount() <= index)
                                throw new IllegalAccessError("Editing value in index " + index + " is not allowed.");
                        if (DEBUG)System.err.println("CELL SET VALUE: " + element + " " + value);
-                       manipulator.setValue((String)value,index);
+                       manipulator.setValue(value.toString(),index);
                        viewer.refresh(item);
-                       nodeMap.commit("Set " + item.id + " value to " + value);
+                       nodeMap.commit("Set " + item.getId() + " value to " + value);
                        
                }
                
@@ -812,12 +967,12 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                
                @Override
                public void update(ViewerCell cell) {
-                       PropertyItem item = (PropertyItem)cell.getElement();
+                       IPropertyItem item = (IPropertyItem)cell.getElement();
 
-                       if (item.name.length() > 0)
-                               cell.setText(item.name);
+                       if (item.getName().length() > 0)
+                               cell.setText(item.getName());
                        else
-                               cell.setText(item.id);
+                               cell.setText(item.getId());
                        
                        
                }
@@ -833,7 +988,7 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                
                @Override
                public void update(ViewerCell cell) {
-                       PropertyItem item = (PropertyItem)cell.getElement();
+                       IPropertyItem item = (IPropertyItem)cell.getElement();
                        int index = cell.getColumnIndex() -1;
                        PropertyManipulator manipulator = tab.getManipulator(item);//createManipulator(item, object);
                        if (manipulator.getValueCount() <= index)
@@ -969,9 +1124,9 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                        if (focusCellManager != null) {
                                try {
                                        Method m = focusCellManager.getClass().getSuperclass()
-                                                       .getDeclaredMethod("init", null);
+                                                       .getDeclaredMethod("init");
                                        m.setAccessible(true);
-                                       m.invoke(focusCellManager, null);
+                                       m.invoke(focusCellManager);
                                } catch (SecurityException e) {
                                        e.printStackTrace();
                                } catch (IllegalArgumentException e) {
@@ -1039,9 +1194,10 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                                if (DEBUG)System.err.println("FOCUS CELL: " + focusCell);
                                                
                                                Method m = AbstractTableViewer.class.getDeclaredMethod(
-                                                               "getSelectionFromWidget", null);
+                                                               "getSelectionFromWidget");
                                                m.setAccessible(true);
-                                               List l = (List) m.invoke(getViewer(), null);
+                                               @SuppressWarnings("rawtypes")
+                                               List l = (List) m.invoke(getViewer());
                                                if (focusCellManager != null) {
                                                        m = focusCellManager
                                                                        .getClass()
@@ -1141,9 +1297,9 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                        ViewerColumn column = (ViewerColumn) m.invoke(viewer,
                                                        new Object[] { new Integer(columnIndex) });
                                        m = ViewerColumn.class.getDeclaredMethod(
-                                                       "getEditingSupport", null);
+                                                       "getEditingSupport");
                                        m.setAccessible(true);
-                                       EditingSupport es = (EditingSupport) m.invoke(column, null);
+                                       EditingSupport es = (EditingSupport) m.invoke(column);
                                        if (column != null && es != null) {
                                                m = EditingSupport.class.getDeclaredMethod("canEdit",
                                                                new Class[] { Object.class });
@@ -1247,10 +1403,9 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
                                m.setAccessible(true);
                                ViewerColumn column = (ViewerColumn) m.invoke(viewer,
                                                new Object[] { new Integer(cell.getColumnIndex()) });
-                               m = ViewerColumn.class.getDeclaredMethod("getEditingSupport",
-                                               null);
+                               m = ViewerColumn.class.getDeclaredMethod("getEditingSupport");
                                m.setAccessible(true);
-                               EditingSupport es = (EditingSupport) m.invoke(column, null);
+                               EditingSupport es = (EditingSupport) m.invoke(column);
                                if (column != null && es != null) {
                                        m = EditingSupport.class.getDeclaredMethod("canEdit",
                                                        new Class[] { Object.class });