You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by jo...@apache.org on 2008/09/16 23:17:32 UTC

svn commit: r696066 - /incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java

Author: joern
Date: Tue Sep 16 14:17:32 2008
New Revision: 696066

URL: http://svn.apache.org/viewvc?rev=696066&view=rev
Log:
UIMA-1098 Extended the quick annotate dialog with key shortcuts

Modified:
    incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java

Modified: incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java
URL: http://svn.apache.org/viewvc/incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java?rev=696066&r1=696065&r2=696066&view=diff
==============================================================================
--- incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java (original)
+++ incubator/uima/sandbox/trunk/CasEditor/src/main/java/org/apache/uima/caseditor/editor/QuickTypeSelectionDialog.java Tue Sep 16 14:17:32 2008
@@ -19,13 +19,21 @@
 
 package org.apache.uima.caseditor.editor;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.eclipse.jface.dialogs.PopupDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.IOpenListener;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ITreeContentProvider;
@@ -39,6 +47,7 @@
 import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
@@ -58,18 +67,112 @@
   private final AnnotationEditor editor;
 
   private Text filterText;
-
+  
+  private Map<Character, Type> shortcutTypeMap = new HashMap<Character, Type>();
+  
+  private Map<Type, Character> typeShortcutMap = new HashMap<Type, Character>();
+
+  /**
+   * Initializes the current instance.
+   * 
+   * @param parent
+   * @param editor
+   */
   QuickTypeSelectionDialog(Shell parent, AnnotationEditor editor) {
-    super(parent, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE, true, true, false, true, null, null);
+    super(parent, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE, true, true, 
+    			false, true, null, null);
 
     this.editor = editor;
+    
+    // key shortcuts are assigned automatically to types, the shortcut 
+    // mapping may change if the type system is modified
+    
+    String shortcutsString = "qwertzuiopasdfghjklyxcvbnm1234567890";
+    
+    Set<Character> shortcuts = new HashSet<Character>();
+    
+    for (int i = 0; i < shortcutsString.length(); i++) {
+    	shortcuts.add(shortcutsString.charAt(i));
+    }
+    
+    Set<Type> types = new HashSet<Type>();
+   	Collections.addAll(types, getTypes());		
+   	
+   	// Try to create mappings with first letter of the type name as shortcut
+   	for (Iterator<Type> it = types.iterator(); it.hasNext();) {
+   		
+   		Type type = it.next();
+   		
+   		String name = type.getShortName();
+   		
+   		Character candidateChar = Character.toLowerCase(name.charAt(0));
+   		
+   		if (shortcuts.contains(candidateChar)) {
+   			putShortcut(candidateChar, type);
+   			
+   			shortcuts.remove(candidateChar);
+   			it.remove();
+   		}
+   	}
+   	
+   	// Now assign letters to the remaining types
+   	for (Iterator<Type> it = types.iterator(); it.hasNext();) {
+   		
+   		if (shortcuts.size() > 0) {
+   			
+   			Character candidateChar = shortcuts.iterator().next();
+   			
+   			putShortcut(candidateChar, it.next());
+   			
+   			shortcuts.remove(candidateChar);
+   			it.remove();
+   		}
+   	}
+  }
+  
+  private void putShortcut(Character shortcut, Type type) {
+	  shortcutTypeMap.put(shortcut, type);
+	  typeShortcutMap.put(type, shortcut);
   }
+  
+  @SuppressWarnings("unchecked")
+  private Type[] getTypes() {
+	  
+	  TypeSystem typeSystem = editor.getDocument().getCAS().getTypeSystem();
+	  
+      List<Type> types = typeSystem.getProperlySubsumedTypes(typeSystem
+              .getType(CAS.TYPE_NAME_ANNOTATION));
 
+      return types.toArray(new Type[types.size()]);
+  }
+  
+  private void annotateAndClose(Type annotationType) {
+		if (annotationType != null) {
+			Point textSelection = editor.getSelection();
+
+			AnnotationFS annotation = editor.getDocument().getCAS()
+					.createAnnotation(annotationType, textSelection.x,
+							textSelection.y);
+
+			editor.getDocument().addFeatureStructure(annotation);
+
+			if (annotation.getType().equals(editor.getAnnotationMode())) {
+				editor.setAnnotationSelection(annotation);
+			}
+		}
+
+		QuickTypeSelectionDialog.this.close();
+	}
+  
   @Override
   protected Control createDialogArea(Composite parent) {
     Composite composite = (Composite) super.createDialogArea(parent);
 
-    filterText = new Text(composite, SWT.NONE);
+    // TODO: focus always goes to the text box, but should
+    // go to the Tree control, find out why, can SWT.NO_FOCUS be used
+    // to fix it ?
+    
+    filterText = new Text(composite, SWT.NO_FOCUS);
     filterText.setBackground(parent.getBackground());
     filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
@@ -80,11 +183,20 @@
     typeTree.getControl().setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
             GridData.FILL_VERTICAL));
 
+    typeTree.getControl().setFocus();
+    
     filterText.addKeyListener(new KeyListener() {
 
       public void keyPressed(KeyEvent e) {
         if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.ARROW_UP) {
           typeTree.getControl().setFocus();
+          
+          Tree tree = (Tree) typeTree.getControl();
+          
+          if (tree.getItemCount() > 0) {
+        	  
+        	  tree.setSelection(tree.getItem(0));
+          }
         }
       }
 
@@ -108,12 +220,7 @@
       }
 
       public Object[] getElements(Object inputElement) {
-        TypeSystem typeSystem = (TypeSystem) inputElement;
-
-        List types = typeSystem.getProperlySubsumedTypes(typeSystem
-                .getType(CAS.TYPE_NAME_ANNOTATION));
-
-        return types.toArray();
+    	  return (Type[]) inputElement;
       }
 
       public void dispose() {
@@ -134,6 +241,55 @@
       }
     } });
 
+    
+    typeTree.setLabelProvider(new ILabelProvider(){
+
+		public Image getImage(Object element) {
+			return null;
+		}
+
+		public String getText(Object element) {
+			
+			Type type = (Type) element;
+			
+			Character key = typeShortcutMap.get(type);
+			
+			if (typeShortcutMap != null) {
+				return "[" + key +"] " + type.getShortName();
+			}
+			else {
+				return type.getShortName();
+			}
+		}
+
+		public void addListener(ILabelProviderListener listener) {
+			
+		}
+
+		public void dispose() {
+		}
+
+		public boolean isLabelProperty(Object element, String property) {
+			return false;
+		}
+
+		public void removeListener(ILabelProviderListener listener) {
+		}});
+    
+    typeTree.getControl().addKeyListener(new KeyListener() {
+
+		public void keyPressed(KeyEvent e) {
+        	Type type = shortcutTypeMap.get(Character.toLowerCase(e.character));
+        	
+        	if (type != null) {
+        		annotateAndClose(type);
+        	}
+		}
+
+		public void keyReleased(KeyEvent e) {
+		}});
+    
+    
     typeTree.getControl().addMouseMoveListener(new MouseMoveListener() {
 
       public void mouseMove(MouseEvent e) {
@@ -148,37 +304,24 @@
       }
     });
 
+    // TODO open listener needs a double click, single click should be enough
+    // because there is already a selection below the mouse
     typeTree.addOpenListener(new IOpenListener() {
 
       public void open(OpenEvent event) {
-
         StructuredSelection selection = (StructuredSelection) event.getSelection();
 
-        Type annotationType = (Type) selection.getFirstElement();
-
-        if (annotationType != null) {
-          Point textSelection = editor.getSelection();
-
-          AnnotationFS annotation = editor.getDocument().getCAS().createAnnotation(annotationType,
-                  textSelection.x, textSelection.y);
-
-          editor.getDocument().addFeatureStructure(annotation);
-
-          if (annotation.getType().equals(editor.getAnnotationMode())) {
-            editor.setAnnotationSelection(annotation);
-          }
-        }
-
-        QuickTypeSelectionDialog.this.close();
+        annotateAndClose((Type) selection.getFirstElement());
       }
     });
 
-    typeTree.setInput(editor.getDocument().getCAS().getTypeSystem());
+    typeTree.setInput(getTypes());
 
-    ISelection modeSelection = new StructuredSelection(new Object[] { editor.getAnnotationMode() });
+    ISelection modeSelection = new StructuredSelection(new Object[] {
+    		editor.getAnnotationMode()});
 
     typeTree.setSelection(modeSelection, true);
-
+    
     return composite;
   }