import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
public static final String DEFAULT_READ_NAME_PREFIX = "Read ";
public static final String CONSENSUS_NAME = "Consensus";
-
+
private final ConversationHolder conversationHolder;
-
private final AlignmentModelChangeListener DIRTY_LISTENER = new AlignmentModelChangeListener() {
@Override
public <T> void afterTokenChange(TokenChangeEvent<T> e) {
setDirty();
}
};
+ private final AlignmentEditorActionUpdater ACTION_UPDATER = new AlignmentEditorActionUpdater();
+
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;
}
-
+
private void refreshToolbarElement(String id) {
ICommandService commandService =
(ICommandService)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getService(ICommandService.class);
}
}
-
+
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);
- }
+ 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);
- }
- });
+ @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);
return result;
}
-
+
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() {
if (alignmentsContainer == null) {
alignmentsContainer = new MultipleAlignmentsContainer();
-
+
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);
}
return alignmentsContainer;
}
-
+
public AlignmentArea getReadsArea() {
return getAlignmentsContainer().getAlignmentAreas().get(READS_AREA_INDEX);
}
-
- 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 childHasFocus((Composite)area.getToolkitComponent());
+ }
+
+
+ public static boolean childHasFocus(Composite parent) { //TODO Move to bioinfweb.commons.swt
+ return isChildComponent(parent, Display.getCurrent().getFocusControl());
+ }
+
+
+ public static boolean isChildComponent(Composite parent, Control child) { //TODO Move to bioinfweb.commons.swt
+ while ((child != parent) && (child != null)) {
+ child = child.getParent();
+ }
+ return (child == parent);
+ }
+
public boolean hasPherogram(int sequenceID) {
return getReadsArea().getDataAreas().getSequenceAreas(sequenceID).size() > PHEROGRAM_AREA_INDEX;
}
-
+
public PherogramArea getPherogramArea(int sequenceID) {
if (hasPherogram(sequenceID)) {
return (PherogramArea)getReadsArea().getDataAreas().getSequenceAreas(sequenceID).get(PHEROGRAM_AREA_INDEX);
}
}
-
+
private ConsensusSequenceArea getConsensusHintDataArea() {
return (ConsensusSequenceArea)getAlignmentsContainer().getAlignmentAreas().
get(CONSENSUS_HINT_AREA_INDEX).getDataAreas().getBottomAreas().
get(CONSENSUS_DATA_AREA_INDEX);
}
-
+
@Deprecated //TODO Remove as soon as testing period is over
private void createTestContents() {
// Just for testing:
}
}
-
+
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).
//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) {
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) {
}
}
+
+ @Override
+ public void dispose() {
+ Display.getCurrent().removeFilter(SWT.FocusIn, ACTION_UPDATER);
+ Display.getCurrent().removeFilter(SWT.FocusOut, ACTION_UPDATER);
+ super.dispose();
+ }
- private void updateStatusBar() {
+
+ private void updateStatusBar() {
IActionBars bars = getEditorSite().getActionBars();
bars.getStatusLineManager().setMessage("Edit mode: " +
(getReadsArea().getEditSettings().isInsert() ? "Insert" : "Overwrite") + " " +
(getReadsArea().getEditSettings().isInsertLeftInDataArea() ? "Left" : "Right"));
}
-
+
private SingleReadAlignment.Shift[] convertToCDMShifts(PherogramAreaModel model) {
Iterator<ShiftChange> iterator = model.shiftChangeIterator();
List<Shift> shifts = new ArrayList<SingleReadAlignment.Shift>();
return shifts.toArray(new Shift[]{});
}
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
- */
+
@Override
public void doSave(IProgressMonitor monitor) {
if (getEditorInput() instanceof AlignmentEditorInput) {
singleRead.setEditedSequence(stringProvider.getSequence(id));
- PherogramAreaModel model = getPherogramArea(id).getModel();
- singleRead.setReverseComplement(model.getPherogramProvider() instanceof ReverseComplementPherogramProvider); // Works only if ReverseComplementPherogramProvider instances are not nested.
- singleRead.setShifts(convertToCDMShifts(getPherogramArea(id).getModel()));
- singleRead.setFirstSeqPosition(model.getFirstSeqPos());
- singleRead.setLeftCutPosition(model.getLeftCutPosition());
- singleRead.setRightCutPosition(model.getRightCutPosition());
+ PherogramArea pherogramArea = getPherogramArea(id);
+ if (pherogramArea != null) {
+ PherogramAreaModel model = pherogramArea.getModel();
+ singleRead.setReverseComplement(model.getPherogramProvider() instanceof ReverseComplementPherogramProvider); // Works only if ReverseComplementPherogramProvider instances are not nested.
+ singleRead.setShifts(convertToCDMShifts(getPherogramArea(id).getModel()));
+ singleRead.setFirstSeqPosition(model.getFirstSeqPos());
+ singleRead.setLeftCutPosition(model.getLeftCutPosition());
+ singleRead.setRightCutPosition(model.getRightCutPosition());
+ }
}
if (!conversationHolder.isBound()) {
}
}
-
- /* (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;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
-
- /* (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){
+ if(conversationHolder != null){
conversationHolder.bind();
}
}
-
+
public boolean isInsertMode() {
return getAlignmentsContainer().getEditSettings().isInsert();
}
return getAlignmentsContainer().getEditSettings().isInsertLeftInDataArea();
}
-
+
public void toggleLeftRightInsertionInPherogram() {
getAlignmentsContainer().getEditSettings().toggleInsertLeftInDataArea();
}
-
+
public void toggleInsertOverwrite() {
getAlignmentsContainer().getEditSettings().toggleInsert();
}
-
+
private String cutPherogram(boolean left) {
SelectionModel selection = getReadsArea().getSelection();
if (selection.getCursorHeight() != 1) {
}
}
-
+
public String cutPherogramLeft() {
return cutPherogram(true);
}
-
+
public String cutPherogramRight() {
return cutPherogram(false);
}
-
+
public void reverseComplementSelectedSequences() {
SelectionModel selection = getReadsArea().getSelection();
AlignmentModel<?> model = getReadsArea().getAlignmentModel();
}
}
-
+
/**
* Recreates the whole consensus sequence from all single read sequences. The previous consensus
* sequence is overwritte.
model.insertTokensAt(sequenceID, 0, tokens);
}
-
+
/**
* Updates the current consensus sequence by replacing gaps by the according consensus tokens
* calculated from the single read sequences and extends the consensus sequence if necessary.
}
}
-
+
public static PherogramProvider readPherogram(URI uri) throws IOException, UnsupportedChromatogramFormatException {
PherogramProvider result;
InputStream stream = uri.toURL().openStream();
return result;
}
-
+
private String newReadName() {
int index = 1;
while (getReadsArea().getAlignmentModel().sequenceIDByName(DEFAULT_READ_NAME_PREFIX + index)
return DEFAULT_READ_NAME_PREFIX + index;
}
-
+
public void addRead(URI pherogramURI, boolean reverseComplemented) throws IOException, UnsupportedChromatogramFormatException {
addRead(newReadName(), pherogramURI, reverseComplemented, null, null, null, null, null);
}
-
+
/**
* Adds a new sequence with attached phergram data area to the reads alignment.
* <p>
if (tokens != null) { // If either an edited sequence or a pherogram URI was provided.
provider.insertTokensAt(id, 0, tokens);
- // Create pherogram area:
- PherogramArea pherogramArea = new PherogramArea(getReadsArea().getContentArea(),
- new PherogramAreaModel(pherogramProvider));
-
- // Set position properties and shifts:
- PherogramAreaModel model = pherogramArea.getModel();
- if ((firstSeqPos != null) && (leftCutPos != null)) {
- model.setFirstSeqLeftCutPos(firstSeqPos, leftCutPos);
- }
- if (rightCutPos != null) {
- model.setRightCutPosition(rightCutPos);
- }
- if ((shifts != null) && (shifts.length > 0)) {
- for (int i = 0; i < shifts.length; i++) {
- model.addShiftChange(shifts[i].position, shifts[i].shift);
- }
- setDirty();
- }
-
- // Add pherogram area to GUI:
- pherogramArea.addMouseListener(new PherogramMouseListener(pherogramArea));
- getReadsArea().getDataAreas().getSequenceAreas(id).add(pherogramArea);
- }
+ if (pherogramProvider != null) {
+ // Create pherogram area:
+ PherogramArea pherogramArea = new PherogramArea(getReadsArea().getContentArea(),
+ new PherogramAreaModel(pherogramProvider));
+
+ // Set position properties and shifts:
+ PherogramAreaModel model = pherogramArea.getModel();
+ if ((firstSeqPos != null) && (leftCutPos != null)) {
+ model.setFirstSeqLeftCutPos(firstSeqPos, leftCutPos);
+ }
+ if (rightCutPos != null) {
+ model.setRightCutPosition(rightCutPos);
+ }
+ if ((shifts != null) && (shifts.length > 0)) {
+ for (int i = 0; i < shifts.length; i++) {
+ model.addShiftChange(shifts[i].position, shifts[i].shift);
+ }
+ setDirty();
+ }
+
+ // Add pherogram area to GUI:
+ pherogramArea.addMouseListener(new PherogramMouseListener(pherogramArea));
+ getReadsArea().getDataAreas().getSequenceAreas(id).add(pherogramArea);
+ }
+ }
return id;
}
}
\ No newline at end of file