Merge branch 'LibrAlign' into develop
authorPatrick Plitzner <p.plitzner@bgbm.org>
Wed, 13 Apr 2016 11:29:46 +0000 (13:29 +0200)
committerPatrick Plitzner <p.plitzner@bgbm.org>
Wed, 13 Apr 2016 11:29:46 +0000 (13:29 +0200)
.gitattributes
eu.etaxonomy.taxeditor.molecular/plugin.xml
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/editor/AlignmentEditor.java
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/editor/AlignmentEditorActionUpdater.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AbstractAlignmentEditorHandler.java
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AbstractFocusedAlignmentAreaHandler.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCopyHandler.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCutHandler.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/EditSequenceHandler.java

index c7b12732ea828b23334c43a93041d51136f034dc..877a615a022cb9b9e3ca73dbe3410a5cfe62fb2c 100644 (file)
@@ -963,6 +963,10 @@ eu.etaxonomy.taxeditor.help/src/eu/etaxonomy/taxeditor/help/Activator.java -text
 eu.etaxonomy.taxeditor.help/toc.xml -text
 eu.etaxonomy.taxeditor.help/tocgettingstarted.xml -text
 eu.etaxonomy.taxeditor.help/tocnameparser.xml -text
+eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/editor/AlignmentEditorActionUpdater.java -text
+eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AbstractFocusedAlignmentAreaHandler.java -text
+eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCutHandler.java -text
+eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java -text
 eu.etaxonomy.taxeditor.navigation/.classpath -text
 eu.etaxonomy.taxeditor.navigation/.project -text
 eu.etaxonomy.taxeditor.navigation/META-INF/MANIFEST.MF -text
@@ -1984,4 +1988,4 @@ src/site/site.xml -text
 eu.etaxonomy.taxeditor.cdmlib/.classpath merge=ours
 eu.etaxonomy.taxeditor.cdmlib/build.properties merge=ours
 eu.etaxonomy.taxeditor/eu.etaxonomy.taxeditor.product merge=ours
-eu.etaxonomy.taxeditor/eu.etaxonomy.taxeditor.product.with.jre merge=ours
\ No newline at end of file
+eu.etaxonomy.taxeditor/eu.etaxonomy.taxeditor.product.with.jre merge=ours
index 27b08389f6dac20b20b92b9616be89c1b01a504c..78b734fd1ad72db0d93c26f003d3331af3159af4 100644 (file)
                class="eu.etaxonomy.taxeditor.molecular.handler.ChangePherogramQualityOutputType"
                commandId="eu.etaxonomy.taxeditor.molecular.pherogramComponent.changeQualityOutput">
          </handler>
+         <handler
+               class="eu.etaxonomy.taxeditor.molecular.handler.AlignmentEditorCopyHandler"
+               commandId="org.eclipse.ui.edit.copy">
+            <activeWhen>
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="eu.etaxonomy.taxeditor.molecular.AlignmentEditor">
+                  </equals>
+               </with>
+            </activeWhen>
+         </handler>
+         <handler
+               class="eu.etaxonomy.taxeditor.molecular.handler.AlignmentEditorCutHandler"
+               commandId="org.eclipse.ui.edit.cut">
+            <activeWhen>
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="eu.etaxonomy.taxeditor.molecular.AlignmentEditor">
+                  </equals>
+               </with>
+            </activeWhen>
+         </handler>
+         <handler
+               class="eu.etaxonomy.taxeditor.molecular.handler.AlignmentEditorPasteHandler"
+               commandId="org.eclipse.ui.edit.paste">
+            <activeWhen>
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="eu.etaxonomy.taxeditor.molecular.AlignmentEditor">
+                  </equals>
+               </with>
+            </activeWhen>
+         </handler>
       </extension>
       <extension
             point="org.eclipse.ui.bindings">
index 4934d9a37d4394c85670d8b5f6d792e22ecfeaea..57608d5d8c04625d32347ba0502d6e59f8d5f471 100644 (file)
@@ -10,6 +10,7 @@
 package eu.etaxonomy.taxeditor.molecular.editor;
 
 
+import info.bioinfweb.commons.swt.SWTUtils;
 import info.bioinfweb.libralign.alignmentarea.AlignmentArea;
 import info.bioinfweb.libralign.alignmentarea.selection.SelectionModel;
 import info.bioinfweb.libralign.alignmentarea.tokenpainter.NucleotideTokenPainter;
@@ -52,16 +53,16 @@ import java.util.TreeMap;
 import org.biojava.bio.chromatogram.ChromatogramFactory;
 import org.biojava.bio.chromatogram.UnsupportedChromatogramFormatException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.Action;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.commands.ICommandService;
 import org.eclipse.ui.part.EditorPart;
 
@@ -128,13 +129,16 @@ public class AlignmentEditor extends EditorPart {
                                        setDirty();
                                }
                        };
+       private final AlignmentEditorActionUpdater ACTION_UPDATER = new AlignmentEditorActionUpdater();
+       public final Clipboard CLIPBOARD = new Clipboard(Display.getCurrent());  //TODO Move to global EDITor class.
+
 
     private MultipleAlignmentsContainer alignmentsContainer = null;
     private final Map<Integer, SingleReadAlignment> cdmMap = new TreeMap<Integer, SingleReadAlignment>();  //TODO Move this to ContigSequenceDataProvider
     private boolean dirty = false;
 
-
-    public AlignmentEditor() {
+    public AlignmentEditor()
+    {
        super();
        conversationHolder = CdmStore.createConversation();
        //conversationHolder = null;
@@ -151,34 +155,34 @@ public class AlignmentEditor extends EditorPart {
 
 
     private void registerEditSettingListener(MultipleAlignmentsContainer container) {
-       container.getEditSettings().addListener(new EditSettingsListener() {
-                                       @Override
-                                       public void workingModeChanged(EditSettingsChangeEvent e) {}  // Currently nothing to do
+        container.getEditSettings().addListener(new EditSettingsListener() {
+            @Override
+            public void workingModeChanged(EditSettingsChangeEvent e) {}  // Currently nothing to do
 
-                                       @Override
-                                       public void insertLeftInDataAreaChanged(EditSettingsChangeEvent e) {
-                                               updateStatusBar();
-                                       refreshToolbarElement(ToggleLeftRightInsertionHandler.COMMAND_ID);
-                                       }
+            @Override
+            public void insertLeftInDataAreaChanged(EditSettingsChangeEvent e) {
+                updateStatusBar();
+                refreshToolbarElement(ToggleLeftRightInsertionHandler.COMMAND_ID);
+            }
 
-                                       @Override
-                                       public void insertChanged(EditSettingsChangeEvent e) {
-                                               updateStatusBar();
-                                       refreshToolbarElement(ToggleInsertOverwriteHandler.COMMAND_ID);
-                                       }
-                               });
+            @Override
+            public void insertChanged(EditSettingsChangeEvent e) {
+                updateStatusBar();
+                refreshToolbarElement(ToggleInsertOverwriteHandler.COMMAND_ID);
+            }
+        });
     }
 
 
-  private AlignmentArea createIndexArea(MultipleAlignmentsContainer container, AlignmentArea labeledArea) {
+    private AlignmentArea createIndexArea(MultipleAlignmentsContainer container, AlignmentArea labeledArea) {
                AlignmentArea result = new AlignmentArea(container);
                result.setAllowVerticalScrolling(false);
                result.getDataAreas().getTopAreas().add(new SequenceIndexArea(result.getContentArea(), labeledArea));
                return result;
-  }
+    }
 
 
-  private AlignmentArea createEditableAlignmentArea(MultipleAlignmentsContainer container, boolean allowVerticalScrolling) {
+    private AlignmentArea createEditableAlignmentArea(MultipleAlignmentsContainer container, boolean allowVerticalScrolling) {
                AlignmentArea result = new AlignmentArea(container);
                result.setAllowVerticalScrolling(allowVerticalScrolling);
 
@@ -195,12 +199,12 @@ public class AlignmentEditor extends EditorPart {
     private AlignmentArea createConsensusHintArea(MultipleAlignmentsContainer container,
                AlignmentArea labeledArea) {
 
-               AlignmentArea result = new AlignmentArea(container);
-               result.setAllowVerticalScrolling(false);
-               result.getDataAreas().getBottomAreas().add(
-                               new ConsensusSequenceArea(result.getContentArea(), labeledArea));
-               return result;
-         }
+               AlignmentArea result = new AlignmentArea(container);
+               result.setAllowVerticalScrolling(false);
+               result.getDataAreas().getBottomAreas().add(
+                               new ConsensusSequenceArea(result.getContentArea(), labeledArea));
+               return result;
+    }
 
 
     private MultipleAlignmentsContainer getAlignmentsContainer() {
@@ -209,9 +213,12 @@ public class AlignmentEditor extends EditorPart {
 
                AlignmentAreaList list = alignmentsContainer.getAlignmentAreas();
                AlignmentArea readsArea = createEditableAlignmentArea(alignmentsContainer, true);
+               readsArea.getSelection().addSelectionListener(ACTION_UPDATER);
            list.add(createIndexArea(alignmentsContainer, readsArea));
                list.add(readsArea);  // Make sure READS_AREA_INDEX is correct.
-               list.add(createEditableAlignmentArea(alignmentsContainer, false));  // Make sure COMSENSUS_AREA_INDEX is correct.
+               AlignmentArea editableConsensusArea = createEditableAlignmentArea(alignmentsContainer, false);
+               editableConsensusArea.getSelection().addSelectionListener(ACTION_UPDATER);
+               list.add(editableConsensusArea);  // Make sure COMSENSUS_AREA_INDEX is correct.
                list.add(createConsensusHintArea(alignmentsContainer, readsArea));
 
                registerEditSettingListener(alignmentsContainer);
@@ -225,11 +232,49 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-    private AlignmentArea getEditableConsensusArea() {
+    public AlignmentArea getEditableConsensusArea() {
        return getAlignmentsContainer().getAlignmentAreas().get(EDITABLE_CONSENSUS_AREA_INDEX);
     }
 
 
+    /**
+     * Checks whether {@link #getReadsArea()} or {@link #getEditableConsensusArea()} currently
+     * have the user focus and returns the according component.
+     *
+     * @return either the reads or the consensus alignment area or {@code null} if none of these
+     *         components is currently focused
+     */
+    public AlignmentArea getFocusedArea() {
+       AlignmentArea result = getReadsArea();
+       if (hasFocus(result)) {
+               return result;
+       }
+       else {
+               result = getEditableConsensusArea();
+               if (hasFocus(result)) {
+                       return result;
+               }
+               else {
+                       return null;
+               }
+       }
+    }
+
+
+    /**
+     * Checks whether the specified alignment area or one of its subcomponents currently has the
+     * focus.
+     *
+     * @param area the alignment area to be checked (Can only be {@link #getReadsArea()} or
+     *        {@link #getEditableConsensusArea()}.)
+     * @return {@code true} if the specified component is focused and is either equal to
+     *         {@link #getReadsArea()} or {@link #getEditableConsensusArea()}or {@code false} otherwise
+     */
+    private boolean hasFocus(AlignmentArea area) {
+       return SWTUtils.childHasFocus((Composite)area.getToolkitComponent());
+    }
+
+
     public boolean hasPherogram(int sequenceID) {
         return getReadsArea().getDataAreas().getSequenceAreas(sequenceID).size() > PHEROGRAM_AREA_INDEX;
     }
@@ -312,12 +357,11 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-       /* (non-Javadoc)
-     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
-     */
     @Override
     public void createPartControl(Composite parent) {
                SWTComponentFactory.getInstance().getSWTComponent(getAlignmentsContainer(), parent, SWT.NONE);
+               Display.getCurrent().addFilter(SWT.FocusIn, ACTION_UPDATER);
+               Display.getCurrent().addFilter(SWT.FocusOut, ACTION_UPDATER);
                updateStatusBar();
 
                if (getEditorInput() instanceof AlignmentEditorInput) {
@@ -340,7 +384,17 @@ public class AlignmentEditor extends EditorPart {
        }
 
 
-    private void updateStatusBar() {
+    @Override
+       public void dispose() {
+               Display.getCurrent().removeFilter(SWT.FocusIn, ACTION_UPDATER);
+               Display.getCurrent().removeFilter(SWT.FocusOut, ACTION_UPDATER);
+               CLIPBOARD.dispose();
+        ((AlignmentEditorInput)getEditorInput()).dispose();
+               super.dispose();
+       }
+
+
+       private void updateStatusBar() {
         IActionBars bars = getEditorSite().getActionBars();
         bars.getStatusLineManager().setMessage("Edit mode: " +
                        (getReadsArea().getEditSettings().isInsert() ? "Insert" : "Overwrite") + "  " +
@@ -360,9 +414,6 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
-     */
     @Override
     public void doSave(IProgressMonitor monitor) {
        if (getEditorInput() instanceof AlignmentEditorInput) {
@@ -432,40 +483,17 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#doSaveAs()
-     */
     @Override
     public void doSaveAs() {}
 
 
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
-     */
     @Override
     public void init(IEditorSite site, IEditorInput input) throws PartInitException {
         setSite(site);
         setInput(input);
-        System.out.println("AlignmentEditor.init(): " + ActionFactory.COPY.getId());
-        site.getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), new Action(ActionFactory.COPY.getId()) {
-            @Override
-            public boolean isEnabled() {
-                System.out.println("isEnabled()");
-                return true;
-            }
-
-            @Override
-            public void run() {
-                System.out.println("run");
-                    super.run();
-                }
-            });
     }
 
 
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#isDirty()
-     */
     @Override
     public boolean isDirty() {
         return dirty;
@@ -478,9 +506,6 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
-     */
     @Override
     public boolean isSaveAsAllowed() {
         return false;  // "Save as" not allowed.
@@ -489,17 +514,12 @@ public class AlignmentEditor extends EditorPart {
 
     @Override
     public void setFocus() {
-        if(conversationHolder!=null){
+        if(conversationHolder != null){
             conversationHolder.bind();
         }
         ((AlignmentEditorInput)getEditorInput()).bind();
     }
 
-    @Override
-    public void dispose() {
-        ((AlignmentEditorInput)getEditorInput()).dispose();
-    }
-
     public boolean isInsertMode() {
         return getAlignmentsContainer().getEditSettings().isInsert();
     }
diff --git a/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/editor/AlignmentEditorActionUpdater.java b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/editor/AlignmentEditorActionUpdater.java
new file mode 100644 (file)
index 0000000..7993a08
--- /dev/null
@@ -0,0 +1,55 @@
+package eu.etaxonomy.taxeditor.molecular.editor;\r
+\r
+\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.actions.ActionFactory;\r
+import org.eclipse.ui.commands.ICommandService;\r
+\r
+import eu.etaxonomy.taxeditor.molecular.handler.AbstractAlignmentEditorHandler;\r
+import info.bioinfweb.libralign.alignmentarea.selection.SelectionChangeEvent;\r
+import info.bioinfweb.libralign.alignmentarea.selection.SelectionListener;\r
+\r
+\r
+\r
+/**\r
+ * Listener used to update copy/paste events associated with {@link AlignmentEditor}.\r
+ * \r
+ * @author Ben Stöver\r
+ * @date 25.08.2015\r
+ */\r
+public class AlignmentEditorActionUpdater implements SelectionListener, Listener {\r
+       private static final String[] IDS = {ActionFactory.COPY.getCommandId(), ActionFactory.CUT.getCommandId(), \r
+               ActionFactory.PASTE.getCommandId()};\r
+       \r
+       \r
+       private void updateEvents() {\r
+               ICommandService service = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class);\r
+               for (int i = 0; i < IDS.length; i++) {\r
+               service.refreshElements(IDS[i], null);\r
+               }\r
+       }\r
+       \r
+       \r
+       @Override\r
+       public void handleEvent(Event event) {\r
+               AlignmentEditor editor = AbstractAlignmentEditorHandler.getActiveAlignmentEditor();\r
+               if (editor != null) {\r
+            updateEvents();\r
+               }\r
+       }\r
+\r
+       \r
+       @Override\r
+       public void selectionChanged(SelectionChangeEvent e) {\r
+               AlignmentEditor editor = AbstractAlignmentEditorHandler.getActiveAlignmentEditor();\r
+               if (editor != null) {\r
+                       if ((e.getSource() == editor.getReadsArea().getSelection()) || \r
+                                       (e.getSource() == editor.getEditableConsensusArea().getSelection())) {\r
+                               \r
+                               updateEvents();\r
+                       }\r
+               }\r
+       }\r
+}\r
index 0c8a6edb1ee5d48d53a2a2fc0753ab2e14c1e836..1d44449b9a5e130df0efa9fe9ab3bf3703b3208f 100644 (file)
@@ -29,15 +29,26 @@ import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;
  * @date 19.06.2015
  */
 public abstract class AbstractAlignmentEditorHandler extends AbstractHandler {
-    @Override
-    public Object execute(ExecutionEvent event) throws ExecutionException {
+       public static AlignmentEditor getActiveAlignmentEditor() {
         IEditorPart activeEditor = AbstractUtility.getActiveEditor();
         if (activeEditor instanceof AlignmentEditor) {
-            doExecute(event, (AlignmentEditor)activeEditor);
+            return (AlignmentEditor)activeEditor;
+        }
+        else {
+               return null;
+        }
+       }
+       
+       
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+       AlignmentEditor editor = getActiveAlignmentEditor();
+        if (editor != null) {
+            doExecute(event, editor);
         }
         return null;
     }
 
 
-    public abstract void doExecute(ExecutionEvent event, AlignmentEditor editor) throws ExecutionException;
+    protected abstract void doExecute(ExecutionEvent event, AlignmentEditor editor) throws ExecutionException;
 }
diff --git a/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AbstractFocusedAlignmentAreaHandler.java b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AbstractFocusedAlignmentAreaHandler.java
new file mode 100644 (file)
index 0000000..1fc418a
--- /dev/null
@@ -0,0 +1,24 @@
+package eu.etaxonomy.taxeditor.molecular.handler;\r
+\r
+\r
+import info.bioinfweb.libralign.alignmentarea.AlignmentArea;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+\r
+import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;\r
+\r
+\r
+\r
+public abstract class AbstractFocusedAlignmentAreaHandler extends AbstractAlignmentEditorHandler {\r
+       @Override\r
+       protected void doExecute(ExecutionEvent event, AlignmentEditor editor) throws ExecutionException {\r
+       AlignmentArea focusedArea = editor.getFocusedArea();\r
+       if (focusedArea != null) {\r
+               doExecute2(event, editor, focusedArea);\r
+       }\r
+       }\r
+       \r
+       \r
+       protected abstract void doExecute2(ExecutionEvent event, AlignmentEditor editor, AlignmentArea focusedArea);\r
+}\r
diff --git a/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCopyHandler.java b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCopyHandler.java
new file mode 100644 (file)
index 0000000..381cf35
--- /dev/null
@@ -0,0 +1,62 @@
+package eu.etaxonomy.taxeditor.molecular.handler;
+
+
+import java.util.Map;
+
+import info.bioinfweb.libralign.alignmentarea.AlignmentArea;
+import info.bioinfweb.libralign.alignmentarea.selection.SelectionModel;
+import info.bioinfweb.libralign.model.AlignmentModelUtils;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.menus.UIElement;
+
+import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;
+
+
+
+/**
+ * Handler that copies the currently selected nucleotides from an alignment editor to the clipboard.
+ * <p>
+ * The copied contents either come from the single reads or the consensus sequence alignment area,
+ * depending on which component currently has the focus. If none of these components has the focus,
+ * nothing will be copied, even if nucleotides are currently selected.
+ * <p>
+ * If the selection contains parts of multiple sequence, these are separated by the line separator
+ * of the current operating system.  
+ * 
+ * @author Ben Stöver
+ * @date 25.08.2015
+ */
+public class AlignmentEditorCopyHandler extends AbstractFocusedAlignmentAreaHandler implements IElementUpdater {
+    @Override
+       @SuppressWarnings("unchecked")
+       protected void doExecute2(ExecutionEvent event, AlignmentEditor editor, AlignmentArea focusedArea) {
+       SelectionModel selection = focusedArea.getSelection();
+       if (!selection.isEmpty()) {
+               editor.CLIPBOARD.setContents(new Object[]{AlignmentModelUtils.selectionAsString(focusedArea, false)}, 
+                       new Transfer[]{TextTransfer.getInstance()});
+       }
+       }
+
+
+       @Override
+       public boolean isEnabled() {
+               AlignmentEditor editor = getActiveAlignmentEditor();
+               if (editor != null) {
+                       AlignmentArea focusedArea = editor.getFocusedArea();
+                       if (focusedArea != null) {
+                               return !focusedArea.getSelection().isEmpty();
+                       }
+               }
+               return false;
+       }
+
+
+       @Override
+       public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) {
+               setBaseEnabled(isEnabled());
+    }
+}
diff --git a/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCutHandler.java b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorCutHandler.java
new file mode 100644 (file)
index 0000000..2236686
--- /dev/null
@@ -0,0 +1,31 @@
+package eu.etaxonomy.taxeditor.molecular.handler;\r
+\r
+\r
+import info.bioinfweb.libralign.alignmentarea.AlignmentArea;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+\r
+import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;\r
+\r
+\r
+\r
+/**\r
+ * Handler that cuts the currently selected nucleotides from an alignment editor to the clipboard.\r
+ * <p>\r
+ * The cut contents either come from the single reads or the consensus sequence alignment area,\r
+ * depending on which component currently has the focus. If none of these components has the focus,\r
+ * nothing will be cut, even if nucleotides are currently selected.\r
+ * <p>\r
+ * If the selection contains parts of multiple sequence, these are separated by the line separator\r
+ * of the current operating system.  \r
+ * \r
+ * @author Ben Stöver\r
+ * @date 25.08.2015\r
+ */\r
+public class AlignmentEditorCutHandler extends AlignmentEditorCopyHandler {\r
+       @Override\r
+       protected void doExecute2(ExecutionEvent event, AlignmentEditor editor, AlignmentArea focusedArea) {\r
+               super.doExecute2(event, editor, focusedArea);  // Copy selected contents.\r
+               focusedArea.getActionProvider().deleteSelection();\r
+       }\r
+}\r
diff --git a/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java
new file mode 100644 (file)
index 0000000..ca03765
--- /dev/null
@@ -0,0 +1,129 @@
+package eu.etaxonomy.taxeditor.molecular.handler;\r
+\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Scanner;\r
+\r
+import info.bioinfweb.libralign.alignmentarea.AlignmentArea;\r
+import info.bioinfweb.libralign.alignmentarea.order.SequenceOrder;\r
+import info.bioinfweb.libralign.alignmentarea.selection.SelectionModel;\r
+import info.bioinfweb.libralign.model.AlignmentModel;\r
+import info.bioinfweb.libralign.model.AlignmentModelUtils;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.dnd.TextTransfer;\r
+import org.eclipse.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.eclipse.ui.menus.UIElement;\r
+\r
+import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor;\r
+\r
+\r
+\r
+/**\r
+ * Handler that pastes the current contents of the clipboard into an active instance of {@link AlignmentEditor}.\r
+ * \r
+ * @author Ben Stöver\r
+ * @date 26.08.2015\r
+ */\r
+public class AlignmentEditorPasteHandler extends AbstractFocusedAlignmentAreaHandler implements IElementUpdater {\r
+       private void pasteString(AlignmentArea area, int sequenceID, String content) {\r
+               area.getActionProvider().deleteSelection();  // Overwrite selected tokens.\r
+               area.getActionProvider().elongateSequence(sequenceID, area.getSelection().getCursorColumn());\r
+\r
+               AlignmentModel<Object> alignmentModel = (AlignmentModel<Object>)area.getAlignmentModel();\r
+               alignmentModel.insertTokensAt(sequenceID, area.getSelection().getCursorColumn(), \r
+                               AlignmentModelUtils.charSequenceToTokenList(content, alignmentModel.getTokenSet(),\r
+                                               true, alignmentModel.getTokenSet().getGapToken()));\r
+       }\r
+       \r
+       \r
+       @Override\r
+       protected void doExecute2(ExecutionEvent event, AlignmentEditor editor, AlignmentArea focusedArea) {\r
+               SelectionModel selection = focusedArea.getSelection();\r
+               String clipboardText = (String)editor.CLIPBOARD.getContents(TextTransfer.getInstance());\r
+               if (clipboardText != null) {\r
+                       List<String> lines = new ArrayList<String>();\r
+                       Scanner scanner = new Scanner(clipboardText);\r
+                       try {\r
+                               while (scanner.hasNext()) {\r
+                                       lines.add(scanner.nextLine());\r
+                               }\r
+                               if (lines.get(lines.size() - 1).equals("")) {\r
+                                       lines.remove(lines.size() - 1);\r
+                               }\r
+                       }\r
+                       finally {\r
+                               scanner.close();\r
+                       }\r
+                       \r
+                       if (!lines.isEmpty()) { //TODO Can lines be empty? (Can an empty string "" be copied to the clipboard?)\r
+                               if (selection.getCursorHeight() == 1) {  // If the consensus sequence is focused, this is the only possible case.\r
+                                       int sequenceID = focusedArea.getSequenceOrder().idByIndex(selection.getCursorRow());\r
+                                       if (lines.size() == 1) {\r
+                                               pasteString(focusedArea, sequenceID, lines.get(0));\r
+                                       }\r
+                                       else {\r
+                                               MessageDialog dialog = new MessageDialog(HandlerUtil.getActiveWorkbenchWindow(event).getShell(),  //TODO Can the window be null? \r
+                                                               "Pasting multiple lines", null,\r
+                                                               "The text to be pasted contains mutlitple lines (" + lines.size() + \r
+                                                               ") although the current cursor height is one. What do you want to do?", \r
+                                                               MessageDialog.QUESTION, \r
+                                                               new String[]{"Ingnore line breaks and paste as one sequence", \r
+                                                                               "Only paste the first line from the clipboard", "Cancel"}, \r
+                                                               0);\r
+                                               //TODO Does the dialog have to be disposed in some way?\r
+                                               \r
+                                               switch (dialog.open()) {\r
+                                                       case 0:  // Paste all lines in one sequence.\r
+                                                               pasteString(focusedArea, sequenceID, clipboardText);\r
+                                                               break;\r
+                                                       case 1:  // Paste only first line.\r
+                                                               pasteString(focusedArea, sequenceID, lines.get(0));\r
+                                                               break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               else {\r
+                                       if (selection.getCursorHeight() == lines.size()) {\r
+                                               SequenceOrder order = focusedArea.getSequenceOrder();\r
+                                               for (int i = 0; i < selection.getCursorHeight(); i++) {\r
+                                                       pasteString(focusedArea, order.idByIndex(selection.getCursorRow() + i), lines.get(i));  // Multiple calls of deleteSelection() in here are unnecessary, but should have no effect.\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               MessageDialog.openError(HandlerUtil.getActiveWorkbenchWindow(event).getShell(),  //TODO Can the window be null?\r
+                                                               "Unable to paste multiple lines", \r
+                                                               "The current cursor height (" + selection.getCursorHeight() + \r
+                                                               ") does not match the number of lines to be pasted (" + lines.size() + ")." + \r
+                                                               System.getProperty("line.separator") + System.getProperty("line.separator") + \r
+                                                               "You can either change the cursor height accordingly or set the cursor height to one "\r
+                                                               + "allowing you to paste all lines from the clipboad into one sequence.");\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       @Override\r
+       public boolean isEnabled() {\r
+               AlignmentEditor editor = getActiveAlignmentEditor();\r
+               if (editor != null) {\r
+                       AlignmentArea focusedArea = editor.getFocusedArea();\r
+                       return (focusedArea != null);\r
+               }\r
+               else {\r
+                       return false;\r
+               }\r
+       }\r
+\r
+\r
+       @Override\r
+       public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) {\r
+               setBaseEnabled(isEnabled());\r
+    }\r
+}\r
index 69597f13d5d6d93b15ee693ea16d6d5a47bbfe69..5c26e4a224f9d512724dc357fd0ceb9dbdef3865 100644 (file)
@@ -24,9 +24,9 @@ import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditorInput;
  * @author pplitzner
  */
 public class EditSequenceHandler extends AbstractHandler {
+    private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(EditSequenceHandler.class);
 
-    org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(EditSequenceHandler.class);
-
+    
     @Override
     public Object execute(ExecutionEvent event) throws ExecutionException {
         ISelection currentSelection = HandlerUtil.getCurrentSelection(event);