package jalview.gui;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.SeqPanel.MousePos;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
+import jalview.util.MessageManager;
import java.awt.Event;
+import java.awt.EventQueue;
import java.awt.event.MouseEvent;
+import java.lang.reflect.InvocationTargetException;
import javax.swing.JLabel;
}
@Test(groups = "Functional")
+ public void testGetEditStatusMessage()
+ {
+ assertNull(SeqPanel.getEditStatusMessage(null));
+
+ EditCommand edit = new EditCommand(); // empty
+ assertNull(SeqPanel.getEditStatusMessage(edit));
+
+ SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
+
+ // 1 gap
+ edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
+ String expected = MessageManager.formatMessage("label.insert_gap", "1");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 3 more gaps makes +4
+ edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
+ expected = MessageManager.formatMessage("label.insert_gaps", "4");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 2 deletes makes + 2
+ edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
+ expected = MessageManager.formatMessage("label.insert_gaps", "2");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 2 more deletes makes 0 - no text
+ edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
+ assertNull(SeqPanel.getEditStatusMessage(edit));
+
+ // 1 more delete makes 1 delete
+ edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
+ expected = MessageManager.formatMessage("label.delete_gap", "1");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 1 more delete makes 2 deletes
+ edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
+ expected = MessageManager.formatMessage("label.delete_gaps", "2");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+ }
+
+ /**
+ * Tests that simulate 'locked editing', where an inserted gap is balanced by
+ * a gap deletion in the selection group, and vice versa
+ */
+ @Test(groups = "Functional")
+ public void testGetEditStatusMessage_lockedEditing()
+ {
+ EditCommand edit = new EditCommand(); // empty
+ SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
+
+ // 1 gap inserted, balanced by 1 delete
+ Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
+ edit.addEdit(e1);
+ Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
+ e2.setSystemGenerated(true);
+ edit.addEdit(e2);
+ String expected = MessageManager.formatMessage("label.insert_gap", "1");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 2 more gaps makes +3
+ Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
+ edit.addEdit(e3);
+ Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
+ e4.setSystemGenerated(true);
+ edit.addEdit(e4);
+ expected = MessageManager.formatMessage("label.insert_gaps", "3");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 2 deletes makes + 1
+ Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
+ edit.addEdit(e5);
+ Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
+ e6.setSystemGenerated(true);
+ edit.addEdit(e6);
+ expected = MessageManager.formatMessage("label.insert_gap", "1");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 1 more delete makes 0 - no text
+ Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
+ edit.addEdit(e7);
+ Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
+ e8.setSystemGenerated(true);
+ edit.addEdit(e8);
+ expected = MessageManager.formatMessage("label.insert_gaps", "2");
+ assertNull(SeqPanel.getEditStatusMessage(edit));
+
+ // 1 more delete makes 1 delete
+ Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
+ edit.addEdit(e9);
+ Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
+ e10.setSystemGenerated(true);
+ edit.addEdit(e10);
+ expected = MessageManager.formatMessage("label.delete_gap", "1");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+
+ // 2 more deletes makes 3 deletes
+ Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
+ edit.addEdit(e11);
+ Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
+ e12.setSystemGenerated(true);
+ edit.addEdit(e12);
+ expected = MessageManager.formatMessage("label.delete_gaps", "3");
+ assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
+ }
+
public void testFindMousePosition_unwrapped()
{
String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
@AfterMethod(alwaysRun = true)
public void tearDown()
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
}
@Test(groups = "Functional")
av.setScaleAboveWrapped(false);
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
- alignFrame.alignPanel.paintAlignment(false, false);
- waitForSwing(); // for Swing thread
+
+ alignFrame.alignPanel.updateLayout();
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
assertEquals(pos.seqIndex, alignmentHeight - 1);
assertEquals(pos.annotationIndex, -1);
- /*
- * cursor at the top of the first annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 0); // over first annotation
-
- /*
- * cursor at the bottom of the first annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 0);
-
- /*
- * cursor at the top of the second annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 1);
-
- /*
- * cursor at the bottom of the second annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 1);
-
- /*
- * cursor at the top of the third annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 2);
-
- /*
- * cursor at the bottom of the third annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 2);
+ AlignmentAnnotation[] annotationRows = av.getAlignment()
+ .getAlignmentAnnotation();
+ for (int n = 0; n < annotationRows.length; n++)
+ {
+ /*
+ * cursor at the top of the n'th annotation
+ */
+ y += 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+ false, 0);
+ pos = testee.findMousePosition(evt);
+ assertEquals(pos.seqIndex, alignmentHeight - 1);
+ assertEquals(pos.annotationIndex, n); // over n'th annotation
+
+ /*
+ * cursor at the bottom of the n'th annotation
+ */
+ y += annotationRows[n].height - 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+ false, 0);
+ pos = testee.findMousePosition(evt);
+ assertEquals(pos.seqIndex, alignmentHeight - 1);
+ assertEquals(pos.annotationIndex, n);
+ }
/*
* cursor in gap between wrapped widths
av.setScaleAboveWrapped(true);
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
- alignFrame.alignPanel.paintAlignment(false, false);
- waitForSwing();
+ alignFrame.alignPanel.updateLayout();
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
assertEquals(pos.seqIndex, alignmentHeight - 1);
assertEquals(pos.annotationIndex, -1);
- /*
- * cursor at the top of the first annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 0); // over first annotation
-
- /*
- * cursor at the bottom of the first annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 0);
-
- /*
- * cursor at the top of the second annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 1);
-
- /*
- * cursor at the bottom of the second annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 1);
-
- /*
- * cursor at the top of the third annotation
- */
- y += 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 2);
-
- /*
- * cursor at the bottom of the third annotation
- */
- y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
- evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
- false, 0);
- pos = testee.findMousePosition(evt);
- assertEquals(pos.seqIndex, alignmentHeight - 1);
- assertEquals(pos.annotationIndex, 2);
+ AlignmentAnnotation[] annotationRows = av.getAlignment().getAlignmentAnnotation();
+ for (int n = 0; n < annotationRows.length; n++)
+ {
+ /*
+ * cursor at the top of the n'th annotation
+ */
+ y += 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+ false, 0);
+ pos = testee.findMousePosition(evt);
+ assertEquals(pos.seqIndex, alignmentHeight - 1);
+ assertEquals(pos.annotationIndex, n); // over n'th annotation
+
+ /*
+ * cursor at the bottom of the n'th annotation
+ */
+ y += annotationRows[n].height - 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+ false, 0);
+ pos = testee.findMousePosition(evt);
+ assertEquals(pos.seqIndex, alignmentHeight - 1);
+ assertEquals(pos.annotationIndex, n);
+ }
/*
* cursor in gap between wrapped widths
av.setScaleAboveWrapped(false);
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
- alignFrame.alignPanel.paintAlignment(false, false);
- waitForSwing();
+ alignFrame.alignPanel.updateLayout();
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
av.setScaleAboveWrapped(false);
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
- alignFrame.alignPanel.paintAlignment(false, false);
- // need to wait for repaint to finish!
- waitForSwing();
+ alignFrame.alignPanel.updateLayout();
SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
int x = 0;
final int charWidth = av.getCharWidth();
* x over scale left (before drawn columns) results in -1
*/
av.setScaleLeftWrapped(true);
- alignFrame.alignPanel.paintAlignment(false, false);
- waitForSwing();
+ alignFrame.alignPanel.updateLayout();
SeqCanvas seqCanvas = testee.seqCanvas;
int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
assertTrue(labelWidth > 0);
* x over scale right (beyond drawn columns) results in -1
*/
av.setScaleRightWrapped(true);
- alignFrame.alignPanel.paintAlignment(false, false);
- waitForSwing();
+ alignFrame.alignPanel.updateLayout();
labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
assertTrue(labelWidth > 0);
int residuesWide2 = av.getRanges().getViewportWidth();
}
/**
- * waits a few ms for Swing to do something
+ * waits for Swing event dispatch queue to empty
*/
synchronized void waitForSwing()
{
try
{
- super.wait(10);
- } catch (InterruptedException e)
+ EventQueue.invokeAndWait(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException e)
{
e.printStackTrace();
}