From ab9f98b3fd7f9125e2ed4900702888d082c2795a Mon Sep 17 00:00:00 2001 From: "b.stoever" Date: Wed, 2 Sep 2015 09:29:44 +0000 Subject: [PATCH] Paste action for AlignmentEditor added. --- .gitattributes | 1 + eu.etaxonomy.taxeditor.molecular/plugin.xml | 12 ++ .../editor/AlignmentEditorActionUpdater.java | 15 +- .../handler/AlignmentEditorPasteHandler.java | 129 ++++++++++++++++++ 4 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java diff --git a/.gitattributes b/.gitattributes index b160a1419..a9c346ed7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -936,6 +936,7 @@ 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 diff --git a/eu.etaxonomy.taxeditor.molecular/plugin.xml b/eu.etaxonomy.taxeditor.molecular/plugin.xml index 503d8e39d..736908429 100644 --- a/eu.etaxonomy.taxeditor.molecular/plugin.xml +++ b/eu.etaxonomy.taxeditor.molecular/plugin.xml @@ -284,6 +284,18 @@ + + + + + + + + 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 index b1f835581..7993a08c4 100644 --- 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 @@ -20,10 +20,14 @@ import info.bioinfweb.libralign.alignmentarea.selection.SelectionListener; * @date 25.08.2015 */ public class AlignmentEditorActionUpdater implements SelectionListener, Listener { - private void updateEvents(String[] ids) { + private static final String[] IDS = {ActionFactory.COPY.getCommandId(), ActionFactory.CUT.getCommandId(), + ActionFactory.PASTE.getCommandId()}; + + + private void updateEvents() { ICommandService service = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class); - for (int i = 0; i < ids.length; i++) { - service.refreshElements(ids[i], null); + for (int i = 0; i < IDS.length; i++) { + service.refreshElements(IDS[i], null); } } @@ -32,8 +36,7 @@ public class AlignmentEditorActionUpdater implements SelectionListener, Listener public void handleEvent(Event event) { AlignmentEditor editor = AbstractAlignmentEditorHandler.getActiveAlignmentEditor(); if (editor != null) { - updateEvents(new String[]{ActionFactory.COPY.getCommandId(), ActionFactory.CUT.getCommandId(), - ActionFactory.PASTE.getCommandId()}); + updateEvents(); } } @@ -45,7 +48,7 @@ public class AlignmentEditorActionUpdater implements SelectionListener, Listener if ((e.getSource() == editor.getReadsArea().getSelection()) || (e.getSource() == editor.getEditableConsensusArea().getSelection())) { - updateEvents(new String[]{ActionFactory.COPY.getCommandId(), ActionFactory.CUT.getCommandId()}); + updateEvents(); } } } 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 index 000000000..4607b2f56 --- /dev/null +++ b/eu.etaxonomy.taxeditor.molecular/src/main/java/eu/etaxonomy/taxeditor/molecular/handler/AlignmentEditorPasteHandler.java @@ -0,0 +1,129 @@ +package eu.etaxonomy.taxeditor.molecular.handler; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +import info.bioinfweb.libralign.alignmentarea.AlignmentArea; +import info.bioinfweb.libralign.alignmentarea.order.SequenceOrder; +import info.bioinfweb.libralign.alignmentarea.selection.SelectionModel; +import info.bioinfweb.libralign.model.AlignmentModel; +import info.bioinfweb.libralign.model.AlignmentModelUtils; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.menus.UIElement; + +import eu.etaxonomy.taxeditor.molecular.editor.AlignmentEditor; + + + +/** + * Handler that pastes the current contents of the clipboard into an active instance of {@link AlignmentEditor}. + * + * @author Ben Stöver + * @date 26.08.2015 + */ +public class AlignmentEditorPasteHandler extends AbstractFocusedAlignmentAreaHandler implements IElementUpdater { + private void pasteString(AlignmentArea area, int sequenceID, String content) { + AlignmentModel alignmentModel = (AlignmentModel)area.getAlignmentModel(); + List tokens = AlignmentModelUtils.charSequenceToTokenList(content, alignmentModel.getTokenSet(), + true, alignmentModel.getTokenSet().getGapToken()); + + area.getActionProvider().deleteSelection(); // Overwrite selected tokens. + area.getActionProvider().elongateSequence(sequenceID, area.getSelection().getCursorColumn()); + alignmentModel.insertTokensAt(sequenceID, area.getSelection().getCursorColumn(), tokens); + } + + + @Override + protected void doExecute2(ExecutionEvent event, AlignmentEditor editor, AlignmentArea focusedArea) { + SelectionModel selection = focusedArea.getSelection(); + String clipboardText = (String)editor.CLIPBOARD.getContents(TextTransfer.getInstance()); + if (clipboardText != null) { + List lines = new ArrayList(); + Scanner scanner = new Scanner(clipboardText); + try { + while (scanner.hasNext()) { + lines.add(scanner.nextLine()); + } + if (lines.get(lines.size() - 1).equals("")) { + lines.remove(lines.size() - 1); + } + } + finally { + scanner.close(); + } + + if (!lines.isEmpty()) { //TODO Can lines be empty? (Can an empty string "" be copied to the clipboard?) + if (selection.getCursorHeight() == 1) { // If the consensus sequence is focused, this is the only possible case. + int sequenceID = focusedArea.getSequenceOrder().idByIndex(selection.getCursorRow()); + if (lines.size() == 1) { + pasteString(focusedArea, sequenceID, lines.get(0)); + } + else { + MessageDialog dialog = new MessageDialog(HandlerUtil.getActiveWorkbenchWindow(event).getShell(), //TODO Can the window be null? + "Pasting multiple lines", null, + "The text to be pasted contains mutlitple lines (" + lines.size() + + ") although the current cursor height is one. What do you want to do?", + MessageDialog.QUESTION, + new String[]{"Ingnore line breaks and paste as one sequence", + "Only paste the first line from the clipboard", "Cancel"}, + 0); + //TODO Does the dialog have to be disposed in some way? + + switch (dialog.open()) { + case 0: // Paste all lines in one sequence. + pasteString(focusedArea, sequenceID, clipboardText); + break; + case 1: // Paste only first line. + pasteString(focusedArea, sequenceID, lines.get(0)); + break; + } + } + } + else { + if (selection.getCursorHeight() == lines.size()) { + SequenceOrder order = focusedArea.getSequenceOrder(); + for (int i = 0; i < selection.getCursorHeight(); i++) { + pasteString(focusedArea, order.idByIndex(selection.getCursorRow() + i), lines.get(i)); // Multiple calls of deleteSelection() in here are unnecessary, but should have no effect. + } + } + else { + MessageDialog.openError(HandlerUtil.getActiveWorkbenchWindow(event).getShell(), //TODO Can the window be null? + "Unable to paste multiple lines", + "The current cursor height (" + selection.getCursorHeight() + + ") does not match the number of lines to be pasted (" + lines.size() + ")." + + System.getProperty("line.separator") + System.getProperty("line.separator") + + "You can either change the cursor height accordingly or set the cursor height to one " + + "allowing you to paste all lines from the clipboad into one sequence."); + } + } + } + } + } + + + @Override + public boolean isEnabled() { + AlignmentEditor editor = getActiveAlignmentEditor(); + if (editor != null) { + AlignmentArea focusedArea = editor.getFocusedArea(); + return (focusedArea != null); + } + else { + return false; + } + } + + + @Override + public void updateElement(UIElement element, @SuppressWarnings("rawtypes") Map parameters) { + setBaseEnabled(isEnabled()); + } +} -- 2.34.1