From: Patric Plitzner Date: Fri, 27 Mar 2015 12:46:41 +0000 (+0000) Subject: merge-update from trunk X-Git-Tag: 3.8.0^2~59^2~73 X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/commitdiff_plain/47794ee9e5b1db905693e1c5cda86ac93e956ead?hp=44b8818937195828b7e200764b02ffd20e3e1632 merge-update from trunk --- diff --git a/.gitattributes b/.gitattributes index 08f910469..801c135a8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -366,6 +366,11 @@ eu.etaxonomy.taxeditor.editor/icons/emblem-photos.png -text eu.etaxonomy.taxeditor.editor/icons/leaf_detail.png -text eu.etaxonomy.taxeditor.editor/icons/link_obj.gif -text eu.etaxonomy.taxeditor.editor/icons/xper64.png -text +eu.etaxonomy.taxeditor.editor/lib/biojava3-alignment-3.0.7.jar -text +eu.etaxonomy.taxeditor.editor/lib/biojava3-core-3.0.7.jar -text +eu.etaxonomy.taxeditor.editor/lib/commons-lang3-3.1.jar -text +eu.etaxonomy.taxeditor.editor/lib/core-1.8.5.jar -text +eu.etaxonomy.taxeditor.editor/lib/sequencing-1.8.5.jar -text eu.etaxonomy.taxeditor.editor/p2.inf -text eu.etaxonomy.taxeditor.editor/plugin.xml -text eu.etaxonomy.taxeditor.editor/pom.xml -text @@ -391,14 +396,21 @@ eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/group/ eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/group/authority/CdmAuthorityEditorInput.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/group/authority/handler/EditCdmAuthoritiesHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/EditNewTaxonHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/EditSequenceHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/FixClassificationHierarchyHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/LoadPherogramHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenAlignmentEditorHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenChecklistEditorHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenDerivateViewHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenParentHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenTaxonEditorHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SaveAllHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SaveTaxonHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ShowPherogramHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SpecimenPropertyTester.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/TaxonParameterConverter.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleInsertOverwriteHandler.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleLeftRightInsertionHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/create/NewNameHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/create/NewPersonHandler.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/create/NewReferenceHandler.java -text @@ -426,6 +438,12 @@ eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/key/po eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/key/polytomous/operation/CreateNodeOperation.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/key/polytomous/operation/DeleteNodeOperation.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/key/polytomous/operation/RefreshNodeNumberingOperation.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditor.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditorInput.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/CDMAlignmentObjectPlaceholder.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/ContigSequenceDataProvider.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramMouseListener.java -text +eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramViewPart.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/TaxonNameEditor.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/container/AbstractGroup.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/container/AbstractGroupedContainer.java -text @@ -614,7 +632,10 @@ eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/v eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/validation/ValidationProblemsView.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/validation/ValidatorClassMarkerField.java -text eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/validation/ValidatorMessageMarkerField.java -text +eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1 -text +eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1 -text eu.etaxonomy.taxeditor.editor/src/main/resources/TaonDescriptionEditor.screen -text +eu.etaxonomy.taxeditor.editor/src/main/resources/TestPherogram_qualityScore.scf -text eu.etaxonomy.taxeditor.editor/src/main/resources/log4j.properties -text eu.etaxonomy.taxeditor.editor/src/test/java/eu/etaxonomy/taxeditor/editor/Application.java -text eu.etaxonomy.taxeditor.editor/src/test/java/eu/etaxonomy/taxeditor/editor/ApplicationActionBarAdvisor.java -text diff --git a/eu.etaxonomy.taxeditor.application/plugin_customization.ini b/eu.etaxonomy.taxeditor.application/plugin_customization.ini index d97cc21c8..736937100 100644 --- a/eu.etaxonomy.taxeditor.application/plugin_customization.ini +++ b/eu.etaxonomy.taxeditor.application/plugin_customization.ini @@ -1,4 +1,5 @@ org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = true org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false org.eclipse.ui/DOCK_PERSPECTIVE_BAR=top-right -org.eclipse.ui/SHOW_TEXT_ON_PERSPECTIVE_BAR=true \ No newline at end of file +org.eclipse.ui/SHOW_TEXT_ON_PERSPECTIVE_BAR=true +org.eclipse.ui/KEY_CONFIGURATION_ID=eu.etaxonomy.taxeditor.bindings.scheme.default \ No newline at end of file diff --git a/eu.etaxonomy.taxeditor.editor/.classpath b/eu.etaxonomy.taxeditor.editor/.classpath index 856e9f909..f7c4e43f8 100644 --- a/eu.etaxonomy.taxeditor.editor/.classpath +++ b/eu.etaxonomy.taxeditor.editor/.classpath @@ -1,9 +1,16 @@ - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/eu.etaxonomy.taxeditor.editor/.project b/eu.etaxonomy.taxeditor.editor/.project index e25293c2f..ce8935ac2 100644 --- a/eu.etaxonomy.taxeditor.editor/.project +++ b/eu.etaxonomy.taxeditor.editor/.project @@ -1,28 +1,40 @@ - - - eu.etaxonomy.taxeditor.editor - NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.pde.PluginNature - - + + + eu.etaxonomy.taxeditor.editor + NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + + + lib/LibrAlign + 2 + WORKSPACE_LOC/LibrAlign/bin + + + lib/bioinfweb.commons + 2 + WORKSPACE_LOC/_Lib/bin + + + diff --git a/eu.etaxonomy.taxeditor.editor/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.editor/META-INF/MANIFEST.MF index 757c5cea5..54ae0db6f 100644 --- a/eu.etaxonomy.taxeditor.editor/META-INF/MANIFEST.MF +++ b/eu.etaxonomy.taxeditor.editor/META-INF/MANIFEST.MF @@ -177,4 +177,11 @@ Bundle-ClassPath: ., jdimodel.jar, pdebuild.jar, compatibility.jar, - junit.jar + junit.jar, + lib/biojava3-alignment-3.0.7.jar, + lib/biojava3-core-3.0.7.jar, + lib/core-1.8.5.jar, + lib/sequencing-1.8.5.jar, + lib/bioinfweb.commons/, + lib/LibrAlign/, + lib/commons-lang3-3.1.jar diff --git a/eu.etaxonomy.taxeditor.editor/build.properties b/eu.etaxonomy.taxeditor.editor/build.properties index df9378660..8486515b2 100644 --- a/eu.etaxonomy.taxeditor.editor/build.properties +++ b/eu.etaxonomy.taxeditor.editor/build.properties @@ -7,4 +7,11 @@ bin.includes = META-INF/,\ p2.inf,\ OSGI-INF/l10n/plugin.properties,\ OSGI-INF/l10n/plugin_de.properties,\ - OSGI-INF/l10n/plugin_en.properties + OSGI-INF/l10n/plugin_en.properties,\ + lib/biojava3-alignment-3.0.7.jar,\ + lib/biojava3-core-3.0.7.jar,\ + lib/core-1.8.5.jar,\ + lib/sequencing-1.8.5.jar,\ + lib/bioinfweb.commons/,\ + lib/LibrAlign/,\ + lib/commons-lang3-3.1.jar diff --git a/eu.etaxonomy.taxeditor.editor/lib/biojava3-alignment-3.0.7.jar b/eu.etaxonomy.taxeditor.editor/lib/biojava3-alignment-3.0.7.jar new file mode 100644 index 000000000..e5f1d6bad Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/lib/biojava3-alignment-3.0.7.jar differ diff --git a/eu.etaxonomy.taxeditor.editor/lib/biojava3-core-3.0.7.jar b/eu.etaxonomy.taxeditor.editor/lib/biojava3-core-3.0.7.jar new file mode 100644 index 000000000..c9f1f81f4 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/lib/biojava3-core-3.0.7.jar differ diff --git a/eu.etaxonomy.taxeditor.editor/lib/commons-lang3-3.1.jar b/eu.etaxonomy.taxeditor.editor/lib/commons-lang3-3.1.jar new file mode 100644 index 000000000..a85e539b1 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/lib/commons-lang3-3.1.jar differ diff --git a/eu.etaxonomy.taxeditor.editor/lib/core-1.8.5.jar b/eu.etaxonomy.taxeditor.editor/lib/core-1.8.5.jar new file mode 100644 index 000000000..c6c7bdc54 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/lib/core-1.8.5.jar differ diff --git a/eu.etaxonomy.taxeditor.editor/lib/sequencing-1.8.5.jar b/eu.etaxonomy.taxeditor.editor/lib/sequencing-1.8.5.jar new file mode 100644 index 000000000..b987ebee8 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/lib/sequencing-1.8.5.jar differ diff --git a/eu.etaxonomy.taxeditor.editor/plugin.xml b/eu.etaxonomy.taxeditor.editor/plugin.xml index 20254cc3e..3aca8a587 100644 --- a/eu.etaxonomy.taxeditor.editor/plugin.xml +++ b/eu.etaxonomy.taxeditor.editor/plugin.xml @@ -83,8 +83,15 @@ id="eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor" name="%editor.name.8"> + + + + - - + @@ -226,8 +239,7 @@ name="%marker.field.7"> - - + + @@ -716,6 +733,28 @@ label="%command.label.54" style="push"> + + + + + + + + + + + + @@ -933,6 +972,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1074,6 +1169,18 @@ + + + + + + + + + + + + - + + + + + + + + + + + + + @@ -1577,6 +1719,24 @@ + + + + + + + + + + + + @@ -1601,6 +1761,13 @@ properties="isGroup" type="eu.etaxonomy.taxeditor.bulkeditor.BulkEditor"> + + @@ -1609,6 +1776,11 @@ id="eu.etaxonomy.taxeditor.bindings.scheme.default" name="%scheme.name"> + + diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java index c93501452..d923dd9b8 100644 --- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java @@ -37,6 +37,8 @@ import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditorInput; import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin; import eu.etaxonomy.taxeditor.editor.key.KeyEditor; import eu.etaxonomy.taxeditor.editor.key.polytomous.PolytomousKeyEditorInput; +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor; +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditorInput; import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor; import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditorInput; import eu.etaxonomy.taxeditor.editor.view.dataimport.BioCaseEditorInput; @@ -120,6 +122,16 @@ public class EditorUtil extends AbstractUtility { open(input, ChecklistEditor.ID); } + /** + * Opens a new AlignmentEditor for the given input + * @param input + * @throws PartInitException + */ + public static void open(AlignmentEditorInput input) + throws PartInitException { + open(input, AlignmentEditor.ID); + } + /** * Opens a new {@link DataImportEditor} for the given input * @param input a {@link DataImportEditorInput} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/EditSequenceHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/EditSequenceHandler.java new file mode 100644 index 000000000..dc41cf1ff --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/EditSequenceHandler.java @@ -0,0 +1,42 @@ +package eu.etaxonomy.taxeditor.editor.handler; + + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeNode; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +import eu.etaxonomy.cdm.model.molecular.Sequence; +import eu.etaxonomy.taxeditor.editor.EditorUtil; +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditorInput; + + + +/** + * Opens the alignment editor from the CDM tree. + * + * @author Ben Stöver + * @author pplitzner + */ +public class EditSequenceHandler extends AbstractHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + TreeNode treeNodeOfSelection = EditorUtil.getTreeNodeOfSelection(currentSelection); + if(treeNodeOfSelection != null && treeNodeOfSelection.getValue() instanceof Sequence){ + AlignmentEditorInput input = new AlignmentEditorInput((Sequence)treeNodeOfSelection.getValue()); //TODO Should there always be a new instance created here? What if the specified CDM node is already opened in an AlignmentEditor? => Possible create Singleton that keeps instances by sequence objects in a map. + try { + EditorUtil.open(input); + } + catch (PartInitException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return null; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/LoadPherogramHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/LoadPherogramHandler.java new file mode 100644 index 000000000..a803a64d6 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/LoadPherogramHandler.java @@ -0,0 +1,69 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.handler; + + +import java.io.File; +import java.io.IOException; + +import org.biojava.bio.chromatogram.UnsupportedChromatogramFormatException; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IEditorPart; + +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor; +import eu.etaxonomy.taxeditor.model.AbstractUtility; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + + + +/** + * Handler that loads an additional read into the contig alignment displayed by an instance of {@link AlignmentEditor}. + * + * @author Ben Stöver + * @author pplitzner + */ +public class LoadPherogramHandler extends AbstractHandler { + //TODO Change so that also URIs which do not point to files can be specified. + + /* (non-Javadoc) + * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart activeEditor = AbstractUtility.getActiveEditor(); + if (activeEditor instanceof AlignmentEditor) { + AlignmentEditor alignmentEditor = (AlignmentEditor)activeEditor; + + FileDialog fileDialog = new FileDialog(alignmentEditor.getSite().getShell()); + fileDialog.setText("Import pherogram into contig alignment"); + fileDialog.setFilterNames(new String[]{"All supported formats", "AB1 pherogram files", "SCF pherogram files", "All files"}); + fileDialog.setFilterExtensions(new String[]{"*.ab1;*.scf", "*.ab1", "*.scf", "*.*"}); + + String path = fileDialog.open(); + if (path != null) { + try { + alignmentEditor.addRead(new File(path).toURI(), false); + } + catch (UnsupportedChromatogramFormatException e) { + MessagingUtils.errorDialog("Unsupported format", this, "The format of the pherogram file \"" + path + + "\" is not supported. (Only AB1 and SCF are supported.)", "eu.etaxonomy.taxeditor.editor", e, false); //TODO set pluginID + } + catch (IOException e) { + MessagingUtils.errorDialog("Unsupported format", this, + "An IO error occurred while trying to read the file \"" + path + "\".", + "/eu.etaxonomy.taxeditor.editor", e, false); //TODO set pluginID + } + } + } + return null; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenAlignmentEditorHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenAlignmentEditorHandler.java new file mode 100644 index 000000000..4350fa29c --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/OpenAlignmentEditorHandler.java @@ -0,0 +1,47 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.handler; + + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; + +import eu.etaxonomy.taxeditor.editor.EditorUtil; +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor; +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditorInput; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + + + +/** + * Opens the {@link AlignmentEditor}. + * + * @author pplitzner + * @date 04.08.2014 + */ +@Deprecated +public class OpenAlignmentEditorHandler extends AbstractHandler { + /* (non-Javadoc) + * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + AlignmentEditorInput input = new AlignmentEditorInput(null); //TODO Does it make sense to start an empty editor? + try { + EditorUtil.open(input); + } + catch (PartInitException e) { + MessagingUtils.error(OpenAlignmentEditorHandler.class, "Could not open AlignmentEditor", e); + } + return null; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ShowPherogramHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ShowPherogramHandler.java new file mode 100644 index 000000000..149e5ceb8 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ShowPherogramHandler.java @@ -0,0 +1,49 @@ +package eu.etaxonomy.taxeditor.editor.handler; + + +import java.net.URI; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeNode; +import org.eclipse.ui.handlers.HandlerUtil; + +import eu.etaxonomy.cdm.model.media.MediaUtils; +import eu.etaxonomy.cdm.model.molecular.SingleRead; +import eu.etaxonomy.taxeditor.editor.EditorUtil; +import eu.etaxonomy.taxeditor.editor.molecular.PherogramViewPart; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + + + +/** + * Displays an undistorted pherogram with {@link PherogramViewPart}. + * + * @author Ben Stöver + * + */ +public class ShowPherogramHandler extends AbstractHandler { + public static void showPherogram(URI uri) { + try { + PherogramViewPart.createView(uri); + } + catch (Exception e) { + MessagingUtils.errorDialog("Error", null, e.getLocalizedMessage(), "eu.etaxonomy.taxeditor.editor", //TODO Is null a valid value here? + e, false); //TODO set pluginID + } + } + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + TreeNode treeNodeOfSelection = EditorUtil.getTreeNodeOfSelection(currentSelection); + if (treeNodeOfSelection != null && treeNodeOfSelection.getValue() instanceof SingleRead) { + showPherogram(MediaUtils.getFirstMediaRepresentationPart( + ((SingleRead)treeNodeOfSelection.getValue()).getPherogram()).getUri()); + } + return null; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SpecimenPropertyTester.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SpecimenPropertyTester.java new file mode 100644 index 000000000..17c821365 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/SpecimenPropertyTester.java @@ -0,0 +1,58 @@ +package eu.etaxonomy.taxeditor.editor.handler; + + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeNode; + +import eu.etaxonomy.cdm.model.molecular.Sequence; +import eu.etaxonomy.cdm.model.molecular.SingleRead; +import eu.etaxonomy.taxeditor.editor.EditorUtil; + + + +/** + * Tests types of specimens to add items to the context menu. + * + * @author pplitzner + * @author BenStoever + */ +public class SpecimenPropertyTester extends PropertyTester { + private static final String SEQUENCE = "isSequence"; + private static final String SINGLE_READ = "isSingleRead"; + + + public SpecimenPropertyTester() {} + + + /* (non-Javadoc) + * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object) + */ + /** {@inheritDoc} */ + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + if (receiver instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) receiver; + TreeNode treeNodeOfSelection = EditorUtil.getTreeNodeOfSelection(selection); + if (treeNodeOfSelection!=null) { + if (SEQUENCE.equals(property)) { + return isSequence(treeNodeOfSelection.getValue()); + } + else if (SINGLE_READ.equals(property)) { + return isSingleReadAlignment(treeNodeOfSelection.getValue()); + } + } + } + return false; + } + + + private boolean isSequence(Object object) { + return (object instanceof Sequence); + } + + + private boolean isSingleReadAlignment(Object object) { + return (object instanceof SingleRead); + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleInsertOverwriteHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleInsertOverwriteHandler.java new file mode 100644 index 000000000..28533af13 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleInsertOverwriteHandler.java @@ -0,0 +1,62 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ + +package eu.etaxonomy.taxeditor.editor.handler; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; + +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor; +import eu.etaxonomy.taxeditor.model.AbstractUtility; + + + +/** + * Switches an {@link AlignmentEditor} between insertion and overwrite mode. + * + * @author Ben Stöver + * @date 04.12.2014 + */ +public class ToggleInsertOverwriteHandler extends AbstractHandler implements IElementUpdater { + public static final String COMMAND_ID = + "eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor.toggleInsertOverwrite"; + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart activeEditor = AbstractUtility.getActiveEditor(); + if (activeEditor instanceof AlignmentEditor) { + ((AlignmentEditor)activeEditor).toggleInsertOverwrite(); + } + return null; + } + + + @Override + public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) { + IEditorPart activeEditor = AbstractUtility.getActiveEditor(); + if (activeEditor instanceof AlignmentEditor) { + if (((AlignmentEditor)activeEditor).isInsertMode()) { + element.setText(" INS "); + element.setTooltip("Click to switch to overwrite mode"); + } + else { + element.setText("OVR"); + element.setTooltip("Click to switch to insertion mode"); + } + } + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleLeftRightInsertionHandler.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleLeftRightInsertionHandler.java new file mode 100644 index 000000000..2173f63d9 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/handler/ToggleLeftRightInsertionHandler.java @@ -0,0 +1,63 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ + +package eu.etaxonomy.taxeditor.editor.handler; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; + +import eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor; +import eu.etaxonomy.taxeditor.model.AbstractUtility; + + + +/** + * Switches an {@link AlignmentEditor} between insertion in the base sequence to the left or to the right. + * + * @author Ben Stöver + * @date 04.12.2014 + */ +public class ToggleLeftRightInsertionHandler extends AbstractHandler implements IElementUpdater { + public static final String COMMAND_ID = + "eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor.toggleLeftRightInsertion"; + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart activeEditor = AbstractUtility.getActiveEditor(); + if (activeEditor instanceof AlignmentEditor) { + ((AlignmentEditor)activeEditor).toggleLeftRightInsertionInPherogram(); + } + return null; + } + + + @Override + public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) { + IEditorPart activeEditor = AbstractUtility.getActiveEditor(); + if (activeEditor instanceof AlignmentEditor) { + //TODO Use icons instead. + if (((AlignmentEditor)activeEditor).isInsertLeftInPherogram()) { + element.setText(" Left "); + element.setTooltip("Click to switch to insert new distorsions of the base call sequence right of future edits."); + } + else { + element.setText("Right"); + element.setTooltip("Click to switch to insert new distorsions of the base call sequence left of future edits."); + } + } + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditor.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditor.java new file mode 100644 index 000000000..75eb41ce6 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditor.java @@ -0,0 +1,548 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import info.bioinfweb.libralign.alignmentarea.AlignmentArea; +import info.bioinfweb.libralign.dataarea.implementations.ConsensusSequenceArea; +import info.bioinfweb.libralign.dataarea.implementations.SequenceIndexArea; +import info.bioinfweb.libralign.dataarea.implementations.pherogram.PherogramAlignmentModel; +import info.bioinfweb.libralign.dataarea.implementations.pherogram.PherogramArea; +import info.bioinfweb.libralign.dataarea.implementations.pherogram.ShiftChange; +import info.bioinfweb.libralign.editsettings.EditSettingsChangeEvent; +import info.bioinfweb.libralign.editsettings.EditSettingsListener; +import info.bioinfweb.libralign.multiplealignments.AlignmentAreaList; +import info.bioinfweb.libralign.multiplealignments.MultipleAlignmentsContainer; +import info.bioinfweb.libralign.pherogram.provider.BioJavaPherogramProvider; +import info.bioinfweb.libralign.pherogram.provider.PherogramProvider; +import info.bioinfweb.libralign.pherogram.provider.ReverseComplementPherogramProvider; +import info.bioinfweb.libralign.sequenceprovider.SequenceDataChangeListener; +import info.bioinfweb.libralign.sequenceprovider.SequenceDataProvider; +import info.bioinfweb.libralign.sequenceprovider.SequenceUtils; +import info.bioinfweb.libralign.sequenceprovider.adapters.StringAdapter; +import info.bioinfweb.libralign.sequenceprovider.events.SequenceChangeEvent; +import info.bioinfweb.libralign.sequenceprovider.events.SequenceRenamedEvent; +import info.bioinfweb.libralign.sequenceprovider.events.TokenChangeEvent; +import info.bioinfweb.libralign.sequenceprovider.implementations.PackedSequenceDataProvider; +import info.bioinfweb.libralign.sequenceprovider.tokenset.BioJavaTokenSet; +import info.bioinfweb.libralign.sequenceprovider.tokenset.TokenSet; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import org.biojava.bio.chromatogram.ChromatogramFactory; +import org.biojava.bio.chromatogram.UnsupportedChromatogramFormatException; +import org.biojava3.core.sequence.compound.DNACompoundSet; +import org.biojava3.core.sequence.compound.NucleotideCompound; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.part.EditorPart; + +import eu.etaxonomy.cdm.api.conversation.ConversationHolder; +import eu.etaxonomy.cdm.api.service.molecular.ISequenceService; +import eu.etaxonomy.cdm.model.media.MediaUtils; +import eu.etaxonomy.cdm.model.molecular.Sequence; +import eu.etaxonomy.cdm.model.molecular.SequenceString; +import eu.etaxonomy.cdm.model.molecular.SingleRead; +import eu.etaxonomy.cdm.model.molecular.SingleReadAlignment; +import eu.etaxonomy.taxeditor.editor.handler.ToggleInsertOverwriteHandler; +import eu.etaxonomy.taxeditor.editor.handler.ToggleLeftRightInsertionHandler; +import eu.etaxonomy.taxeditor.store.CdmStore; + + + +/** + * Editor component to edit a contig alignment used to combine different overlapping pherograms from Sanger sequencing to + * a consensus sequence. + *

+ * The contained GUI components used to edit the alignment come from LibrAlign. + * + * @author Ben Stöver + * @author pplitzner + * @date 04.08.2014 + */ +public class AlignmentEditor extends EditorPart { + public static final String ID = "eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor"; + + private final ConversationHolder conversationHolder; + + public static final int READS_AREA_INDEX = 1; + public static final int CONSENSUS_AREA_INDEX = READS_AREA_INDEX + 1; + public static final int PHEROGRAM_AREA_INDEX = 0; + public static final String DEFAULT_READ_NAME_PREFIX = "Read "; + public static final String CONSENSUS_NAME = "Consensus"; + + + private final SequenceDataChangeListener DIRTY_LISTENER = new SequenceDataChangeListener() { + @Override + public void afterTokenChange(TokenChangeEvent e) { + setDirty(); + } + + @Override + public void afterSequenceRenamed(SequenceRenamedEvent e) { + setDirty(); + } + + @Override + public void afterSequenceChange(SequenceChangeEvent e) { + setDirty(); + } + + @Override + public void afterProviderChanged(SequenceDataProvider oldProvider, + SequenceDataProvider newProvider) { // Not expected. + + setDirty(); + } + }; + + private MultipleAlignmentsContainer alignmentsContainer = null; + private final Map cdmMap = new TreeMap(); //TODO Move this to ContigSequenceDataProvider + private boolean dirty = false; + + public AlignmentEditor() { + conversationHolder = CdmStore.createConversation(); + } + + + private void refreshToolbarElement(String id) { + ICommandService commandService = + (ICommandService)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(ICommandService.class); + if (commandService != null) { + commandService.refreshElements(id, Collections.EMPTY_MAP); + } + } + + + private void registerEditSettingListener(MultipleAlignmentsContainer container) { + 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 insertChanged(EditSettingsChangeEvent e) { + updateStatusBar(); + refreshToolbarElement(ToggleInsertOverwriteHandler.COMMAND_ID); + } + }); + } + + + private AlignmentArea createIndexArea(MultipleAlignmentsContainer container) { + AlignmentArea result = new AlignmentArea(container); + result.setAllowVerticalScrolling(false); + result.getDataAreas().getTopAreas().add(new SequenceIndexArea(result.getContentArea())); + return result; + } + + + private AlignmentArea createEditableAlignmentArea(MultipleAlignmentsContainer container, boolean allowVerticalScrolling) { + AlignmentArea result = new AlignmentArea(container); + result.setAllowVerticalScrolling(allowVerticalScrolling); + + TokenSet tokenSet = new BioJavaTokenSet(new DNACompoundSet(), true); + SequenceDataProvider provider = new PackedSequenceDataProvider(tokenSet); + result.setSequenceProvider(provider, false); + provider.getChangeListeners().add(DIRTY_LISTENER); + + return result; + } + + + private AlignmentArea createConsensusHintArea(MultipleAlignmentsContainer container, + SequenceDataProvider sequenceProvider) { + + AlignmentArea result = new AlignmentArea(container); + result.setAllowVerticalScrolling(false); + result.getDataAreas().getBottomAreas().add( + new ConsensusSequenceArea(result.getContentArea(), sequenceProvider)); + return result; + } + + + private MultipleAlignmentsContainer getAlignmentsContainer() { + if (alignmentsContainer == null) { + alignmentsContainer = new MultipleAlignmentsContainer(); + + AlignmentAreaList list = alignmentsContainer.getAlignmentAreas(); + list.add(createIndexArea(alignmentsContainer)); + AlignmentArea readsArea = createEditableAlignmentArea(alignmentsContainer, true); + list.add(readsArea); // Make sure READS_AREA_INDEX is correct. + list.add(createEditableAlignmentArea(alignmentsContainer, false)); // Make sure COMSENSUS_AREA_INDEX is correct. + list.add(createConsensusHintArea(alignmentsContainer, + readsArea.getSequenceProvider())); + + registerEditSettingListener(alignmentsContainer); + } + return alignmentsContainer; + } + + + private AlignmentArea getReadsArea() { + return getAlignmentsContainer().getAlignmentAreas().get(READS_AREA_INDEX); + } + + + private AlignmentArea getConsensusArea() { + return getAlignmentsContainer().getAlignmentAreas().get(CONSENSUS_AREA_INDEX); + } + + + private PherogramArea getPherogramArea(int sequenceID) { + return (PherogramArea)getReadsArea().getDataAreas().getSequenceAreas(sequenceID).get(PHEROGRAM_AREA_INDEX); + } + + + private void createTestContents() { + // Just for testing: + try { + addRead(new File("D:/Users/BenStoever/Documents/Studium/Projekte/Promotion/EDITor/Quelltexte/LibrAlign branch/Repository/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1").toURI(), false); + addRead(new File("D:/Users/BenStoever/Documents/Studium/Projekte/Promotion/EDITor/Quelltexte/LibrAlign branch/Repository/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1").toURI(), false); + + // Add test consensus sequence: + SequenceDataProvider consensusProvider = getConsensusArea().getSequenceProvider(); + int id = consensusProvider.addSequence(CONSENSUS_NAME); + Collection tokens = new ArrayList(); // First save tokens in a collection to avoid GUI updated for each token. + tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('A')); + tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('C')); + tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('G')); + tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('T')); + consensusProvider.insertTokensAt(id, 0, tokens); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + + private void readCDMData(Sequence sequenceNode) { + //TODO If called from somewhere else than createPartControl() the editorInput needs to be checked and previous contents need to be cleared (or updated). + + // Add reads: + for (SingleReadAlignment singleReadAlignment : sequenceNode.getSingleReadAlignments()) { + try { + SingleRead pherogramInfo = singleReadAlignment.getSingleRead(); + int id = addRead(pherogramInfo.getPrimer().getLabel(), //TODO Should the sequence name contain other/additional/alternative data? Can the same string as in the derivative tree be used here? + MediaUtils.getFirstMediaRepresentationPart(pherogramInfo.getPherogram()).getUri(), + singleReadAlignment.isReverseComplement(), + singleReadAlignment.getEditedSequence(), + singleReadAlignment.getShifts()); + cdmMap.put(id, singleReadAlignment); + } + catch (IOException e) { + e.printStackTrace(); //TODO Output to user (Possibly collect for all pherograms and display in the end.) + } + catch (UnsupportedChromatogramFormatException e) { + e.printStackTrace(); //TODO Output to user (Possibly collect for all pherograms and display in the end.) + } + } + + // Set consensus sequence: + SequenceDataProvider consensusProvider = getConsensusArea().getSequenceProvider(); + int id = consensusProvider.addSequence(CONSENSUS_NAME); + consensusProvider.insertTokensAt(id, 0, SequenceUtils.stringToTokenList( + sequenceNode.getConsensusSequence().getString(), consensusProvider.getTokenSet())); + //TODO Can the consensus sequence also be null? / Should it be created here, if nothing is in the DB? + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + getAlignmentsContainer().createSWTWidget(parent, SWT.NONE); + updateStatusBar(); + + if (getEditorInput() instanceof AlignmentEditorInput) { + if (((AlignmentEditorInput)getEditorInput()).getSequenceNode() != null) { + Sequence sequenceNode = ((AlignmentEditorInput)getEditorInput()).getSequenceNode(); + //re-load into the current session if it is already persisted in the DB + if(sequenceNode!=null && sequenceNode.getId()!=0){ + sequenceNode = CdmStore.getService(ISequenceService.class).load(sequenceNode.getUuid()); + } + readCDMData(sequenceNode); + } + else { + createTestContents(); // This case will removed after the test phase and an exception should probably be thrown. + } + } + else { + throw new IllegalArgumentException("The editor input must have the type " + + AlignmentEditorInput.class.getCanonicalName()); //TODO What should be done here? + } + } + + + private void updateStatusBar() { + IActionBars bars = getEditorSite().getActionBars(); + bars.getStatusLineManager().setMessage("Edit mode: " + + (getReadsArea().getEditSettings().isInsert() ? "Insert" : "Overwrite") + " " + + "Insertion in pherogram: " + + (getReadsArea().getEditSettings().isInsertLeftInDataArea() ? "Left" : "Right")); + } + + + private SingleReadAlignment.Shift[] convertToCDMShifts(PherogramAlignmentModel alignmentModel) { + SingleReadAlignment.Shift[] result = new SingleReadAlignment.Shift[alignmentModel.getShiftChangeCount()]; + Iterator iterator = alignmentModel.shiftChangeIterator(); + int pos = 0; + while (iterator.hasNext()) { + ShiftChange shiftChange = iterator.next(); + result[pos] = new SingleReadAlignment.Shift(shiftChange.getBaseCallIndex(), shiftChange.getShiftChange()); + } + return result; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void doSave(IProgressMonitor monitor) { + System.out.println("save 1"); + if (getEditorInput() instanceof AlignmentEditorInput) { + System.out.println("save 2"); + Sequence sequenceNode = ((AlignmentEditorInput)getEditorInput()).getSequenceNode(); + StringAdapter stringProvider = new StringAdapter(getConsensusArea().getSequenceProvider(), false); // Throws an exception if a token has more than one character. + + // Write consensus sequence: + SequenceString consensusSequenceObj = sequenceNode.getConsensusSequence(); + String newConsensusSequence = stringProvider.getSequence( + getConsensusArea().getSequenceProvider().sequenceIDByName(CONSENSUS_NAME)); + if (consensusSequenceObj == null) { + sequenceNode.setConsensusSequence(SequenceString.NewInstance(newConsensusSequence)); + } + else { + consensusSequenceObj.setString(newConsensusSequence); + } + + // Write single reads: + stringProvider.setUnderlyingProvider(getReadsArea().getSequenceProvider()); + sequenceNode.getSingleReadAlignments().retainAll(cdmMap.values()); // Remove all reads that are not in the alignment anymore. + Iterator iterator = getReadsArea().getSequenceProvider().sequenceIDIterator(); + while (iterator.hasNext()) { + int id = iterator.next(); + System.out.println("Saving sequence " + id); + SingleReadAlignment singleRead = cdmMap.get(id); + if (singleRead == null) { + //TODO Create new read object. => Shall it be allowed to add reads in the alignment editor which are not represented in the CDM tree before the alignment editor is saved? + //singleRead = SingleReadAlignment.NewInstance(consensusSequence, singleRead, shifts, editedSequence); + } + + singleRead.setEditedSequence(stringProvider.getSequence(id)); + singleRead.setReverseComplement(getPherogramArea(id).getProvider() instanceof ReverseComplementPherogramProvider); // Works only if ReverseComplementPherogramProvider instances are not nested. + singleRead.setShifts(convertToCDMShifts(getPherogramArea(id).getAlignmentModel())); + System.out.println(singleRead.getShifts()); + } + } + + String taskName = "Saving alignment"; + monitor.beginTask(taskName, 3); + if (!conversationHolder.isBound()) { + conversationHolder.bind(); + } + monitor.worked(1); + + // commit the conversation and start a new transaction immediately + conversationHolder.commit(true); + monitor.worked(1); + + dirty = false; //TODO "*" is not removed from editor title. Why not? (Should be save action in the tool bar be disabled when isDirty() returns false? This is also not the case.) + monitor.worked(1); + monitor.done(); + firePropertyChange(PROP_DIRTY); + } + + + /* (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); + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#isDirty() + */ + @Override + public boolean isDirty() { + return dirty; + } + + + private void setDirty() { + dirty = true; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed() + */ + @Override + public boolean isSaveAsAllowed() { + return false; // "Save as" not allowed. + } + + + @Override + public void setFocus() { + if(conversationHolder!=null){ + conversationHolder.bind(); + } + } + + + public boolean isInsertMode() { + return getAlignmentsContainer().getEditSettings().isInsert(); + } + + + public boolean isInsertLeftInPherogram() { + return getAlignmentsContainer().getEditSettings().isInsertLeftInDataArea(); + } + + + public void toggleLeftRightInsertionInPherogram() { + getAlignmentsContainer().getEditSettings().toggleInsertLeftInDataArea(); + } + + + public void toggleInsertOverwrite() { + getAlignmentsContainer().getEditSettings().toggleInsert(); + } + + + public static PherogramProvider readPherogram(URI uri) throws IOException, UnsupportedChromatogramFormatException { + PherogramProvider result; + InputStream stream = uri.toURL().openStream(); + try { + result = new BioJavaPherogramProvider(ChromatogramFactory.create(stream)); + } + finally { + stream.close(); + } + return result; + } + + + private String newReadName() { + int index = 1; + while (getReadsArea().getSequenceProvider().sequenceIDByName(DEFAULT_READ_NAME_PREFIX + index) + != SequenceDataProvider.NO_SEQUENCE_FOUND) { + + index++; + } + return DEFAULT_READ_NAME_PREFIX + index; + } + + + public void addRead(URI pherogramURI, boolean reverseComplemented) throws IOException, UnsupportedChromatogramFormatException { + addRead(newReadName(), pherogramURI, reverseComplemented, null, null); + } + + + /** + * Adds a new sequence with attached phergram data area to the reads alignment. + *

+ * If {@code null} is specified as {@code editedSequence} the base call sequence from the pherogram will + * be set as the edited sequence. If {@code null} is specified as {@code shifts} no shifts between the edited + * and the base calls sequence are assumed. + * + * @param name the name of the new sequence + * @param pherogramURI the URI where the associated pherogram file is located + * @param reverseComplemented Specify {@code true} here, if the reverse complement of the pherogram data should + * be added, {@code false} otherwise. + * @param editedSequence the edited version of the base call sequence (May be {@code null}.) + * @param shifts the alignment information that links the edited and the base call sequence (May be {@code null}.) + * @return the sequence ID of the added read + * @throws IOException if an error occurred when trying to read the pherogram file + * @throws UnsupportedChromatogramFormatException if the format of the pherogram file is not supported + */ + public int addRead(String name, URI pherogramURI, boolean reverseComplemented, String editedSequence, + SingleReadAlignment.Shift[] shifts) throws IOException, UnsupportedChromatogramFormatException { + + SequenceDataProvider provider = getReadsArea().getSequenceProvider(); + PherogramProvider pherogramProvider = readPherogram(pherogramURI); // Must happen before a sequence is added, because it might throw an exception. + if (reverseComplemented) { + pherogramProvider = new ReverseComplementPherogramProvider(pherogramProvider); + } + + // Create sequence: + provider.addSequence(name); + int id = provider.sequenceIDByName(name); + + // Set edited sequence: + Collection tokens; // First save tokens in a collection to avoid GUI updated for each token. + if (editedSequence != null) { + tokens = SequenceUtils.stringToTokenList(editedSequence, provider.getTokenSet()); + } + else { // Copy base call sequence into alignment: + tokens = new ArrayList(); + for (int i = 0; i < pherogramProvider.getSequenceLength(); i++) { + tokens.add(provider.getTokenSet().tokenByKeyChar( + pherogramProvider.getBaseCall(i).getUpperedBase().charAt(0))); + } + setDirty(); + } + provider.insertTokensAt(id, 0, tokens); + + // Create pherogram area: + PherogramArea pherogramArea = new PherogramArea(getReadsArea().getContentArea(), pherogramProvider); + + // Set shifts: + if (shifts != null) { + PherogramAlignmentModel alignmentModel = pherogramArea.getAlignmentModel(); + for (int i = 0; i < shifts.length; i++) { + alignmentModel.addShiftChange(shifts[i].position, shifts[i].shift); + } + setDirty(); + } + + // Add pherogram area to GUI: + pherogramArea.addMouseListener(new PherogramMouseListener(pherogramURI)); + getReadsArea().getDataAreas().getSequenceAreas(id).add(pherogramArea); + + // Save source URI: + return id; + } +} \ No newline at end of file diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditorInput.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditorInput.java new file mode 100644 index 000000000..9d6201d20 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/AlignmentEditorInput.java @@ -0,0 +1,133 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +import eu.etaxonomy.cdm.model.molecular.Sequence; + + + +/** + * @author pplitzner + * @author Ben Stöver + * @date 04.08.2014 + */ +public class AlignmentEditorInput implements IEditorInput { + private static final String name = "AlignmentEditor"; + + + private final Sequence sequenceNode; + + + public AlignmentEditorInput(Sequence sequenceNode) { + super(); + this.sequenceNode = sequenceNode; + } + + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @Override + public Object getAdapter(Class adapter) { + // TODO Auto-generated method stub + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#exists() + */ + @Override + public boolean exists() { + // TODO Auto-generated method stub + return false; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + @Override + public ImageDescriptor getImageDescriptor() { + // TODO Auto-generated method stub + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + @Override + public String getName() { + return name; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + @Override + public IPersistableElement getPersistable() { + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + @Override + public String getToolTipText() { + return name; + } + + + /** + * Returns the sequence CDM node that should be edited by the {@link AlignmentEditor} this object + * is used with. + * + * @return the CDM node to work on + */ + public Sequence getSequenceNode() { + return sequenceNode; + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((sequenceNode == null) ? 0 : sequenceNode.hashCode()); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AlignmentEditorInput other = (AlignmentEditorInput) obj; + if (sequenceNode == null) { + if (other.sequenceNode != null) + return false; + } else if (!sequenceNode.equals(other.sequenceNode)) + return false; + return true; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/CDMAlignmentObjectPlaceholder.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/CDMAlignmentObjectPlaceholder.java new file mode 100644 index 000000000..859b03a13 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/CDMAlignmentObjectPlaceholder.java @@ -0,0 +1,98 @@ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import info.bioinfweb.libralign.dataarea.implementations.pherogram.ShiftChange; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.biojava3.core.sequence.compound.NucleotideCompound; +import org.biojava3.core.sequence.template.Sequence; + + + +/** + * This class is used as a replacement for a class representing the CMD objects storing an contig alignment during early + * development phase. + * + * @author Ben Stöver + * @date 06.08.2014 + */ +public class CDMAlignmentObjectPlaceholder { + /** + * Represents information in the contig alignment describing a single read sequence and the relation to its associated + * pherogram. + * + * @author Ben Stöver + * @date 06.08.2014 + */ + public static class Read { + private long pherogramObjectID = Long.MIN_VALUE; // The ID used in the CMD to identify the object storing the pherogram URL. (Dont' know if this is long, just as an example-) + private Sequence editableSequence = null; // Could also be of type String, if helpful for CDM architecture. + private List shiftChangeList = new ArrayList(); + private String readName = ""; + private boolean reverseComplemeted = false; + + + public Read(long pherogramObjectID) { + super(); + this.pherogramObjectID = pherogramObjectID; + } + + + public long getPherogramObjectID() { + return pherogramObjectID; + } + + + public void setPherogramObjectID(long pherogramObjectID) { + this.pherogramObjectID = pherogramObjectID; + } + + + public List getShiftChangeList() { + return shiftChangeList; + } + + + public Sequence getEditableSequence() { + return editableSequence; + } + + + public String getReadName() { + return readName; + } + + + public void setReadName(String readName) { + this.readName = readName; + } + + + public boolean isReverseComplemeted() { + return reverseComplemeted; + } + + + public void setReverseComplemeted(boolean reverseComplemeted) { + this.reverseComplemeted = reverseComplemeted; + } + } + + + private Map> consensusSequences = new TreeMap>(); // Could also be of type Map, if helpful for CDM architecture. + private Map readSequences = new TreeMap(); + + + public Map> getConsensusSequences() { + return consensusSequences; + } + + + public Map getReadSequences() { + return readSequences; + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/ContigSequenceDataProvider.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/ContigSequenceDataProvider.java new file mode 100644 index 000000000..893b4eebf --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/ContigSequenceDataProvider.java @@ -0,0 +1,45 @@ +// $Id$ +/** +* Copyright (C) 2014 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import org.biojava3.core.sequence.compound.NucleotideCompound; + +import info.bioinfweb.commons.bio.biojava3.core.sequence.compound.AlignmentAmbiguityDNACompoundSet; +import info.bioinfweb.libralign.sequenceprovider.SequenceDataProvider; +import info.bioinfweb.libralign.sequenceprovider.implementations.PackedSequenceDataProvider; +import info.bioinfweb.libralign.sequenceprovider.tokenset.BioJavaTokenSet; + + + +/** + * The LibrAlign sequence data provider used to edit contig alignments with the {@link AlignmentEditor}. + * + * @author Ben Stöver + * @date 04.08.2014 + */ +public class ContigSequenceDataProvider extends PackedSequenceDataProvider + implements SequenceDataProvider { + + + public ContigSequenceDataProvider() { + super(new BioJavaTokenSet(AlignmentAmbiguityDNACompoundSet.getAlignmentAmbiguityDNACompoundSet(), true)); + } + + + public void saveToCMD() { //TODO Add cmd node as parameter + //TODO impl. + } + + + public void loadFromCMD() { //TODO Add cmd node as parameter + //TODO impl. + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramMouseListener.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramMouseListener.java new file mode 100644 index 000000000..0d3ff3277 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramMouseListener.java @@ -0,0 +1,44 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import info.bioinfweb.commons.tic.input.TICMouseAdapter; +import info.bioinfweb.commons.tic.input.TICMouseEvent; + +import java.net.URI; + +import eu.etaxonomy.taxeditor.editor.handler.ShowPherogramHandler; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + + + +/** + * Listens to mouse events on data areas displaying a pherogram in {@link AlignmentEditor}. + * + * @author Ben Stöver + * @date 25.11.2014 + */ +public class PherogramMouseListener extends TICMouseAdapter { + private URI uri; + + + public PherogramMouseListener(URI uri) { + super(); + this.uri = uri; + } + + + @Override + public void mousePressed(TICMouseEvent event) { + if (event.getClickCount() == 2) { // Double click + ShowPherogramHandler.showPherogram(uri); + } + } +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramViewPart.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramViewPart.java new file mode 100644 index 000000000..b6172eb48 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/molecular/PherogramViewPart.java @@ -0,0 +1,85 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.editor.molecular; + + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; + +import info.bioinfweb.libralign.pherogram.PherogramFormats.QualityOutputType; +import info.bioinfweb.libralign.pherogram.view.PherogramView; + +import org.biojava.bio.chromatogram.UnsupportedChromatogramFormatException; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + + + +/** + * Component that allows to view a pherogram without the distortion due to aligning it to a sequence as in + * {@link AlignmentEditor}. + * + * @author Ben Stöver + * @date Nov 20, 2014 + */ +public class PherogramViewPart extends ViewPart { + public static final String ID = "eu.etaxonomy.taxeditor.editor.molecular.PherogramView"; + + private URI uri = null; + private PherogramView pherogramView = null; + + + public static PherogramViewPart createView(URI uri) throws PartInitException, MalformedURLException, + UnsupportedChromatogramFormatException, IOException { + + PherogramViewPart view = (PherogramViewPart)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(ID); + view.setURI(uri); + return view; + } + + + public PherogramView getPherogramView() { + if (pherogramView == null) { + pherogramView = new PherogramView(); + pherogramView.getTraceCurveView().getFormats().setShowProbabilityValues(true); + pherogramView.getTraceCurveView().setHorizontalScale(1); + pherogramView.getTraceCurveView().setVerticalScale(100); + pherogramView.getTraceCurveView().getFormats().setQualityOutputType(QualityOutputType.NONE); //TODO Make this user defined + pherogramView.getTraceCurveView().getFormats().setShowProbabilityValues(false); + } + return pherogramView; + } + + + public URI getURI() { + return uri; + } + + + protected void setURI(URI uri) throws MalformedURLException, IOException, UnsupportedChromatogramFormatException { + this.uri = uri; + getPherogramView().getTraceCurveView().setProvider(AlignmentEditor.readPherogram(uri)); + getPherogramView().assignSize(); + } + + + @Override + public void createPartControl(Composite parent) { + getPherogramView().createSWTWidget(parent, SWT.NONE); + getPherogramView().assignSize(); + } + + + @Override + public void setFocus() {} // nothing to do +} diff --git a/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1 b/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1 new file mode 100644 index 000000000..83a3be3b3 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1 differ diff --git a/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1 b/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1 new file mode 100644 index 000000000..be62c7cd5 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1 differ diff --git a/eu.etaxonomy.taxeditor.editor/src/main/resources/TestPherogram_qualityScore.scf b/eu.etaxonomy.taxeditor.editor/src/main/resources/TestPherogram_qualityScore.scf new file mode 100644 index 000000000..e680999a3 Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/src/main/resources/TestPherogram_qualityScore.scf differ diff --git a/eu.etaxonomy.taxeditor/.classpath b/eu.etaxonomy.taxeditor/.classpath index 7c95b583f..3446faf90 100644 --- a/eu.etaxonomy.taxeditor/.classpath +++ b/eu.etaxonomy.taxeditor/.classpath @@ -1,12 +1,12 @@ - - - - - - - - - - - - + + + + + + + + + + + +