historyitem added
authoramwaterhouse <Andrew Waterhouse>
Mon, 23 May 2005 09:27:33 +0000 (09:27 +0000)
committeramwaterhouse <Andrew Waterhouse>
Mon, 23 May 2005 09:27:33 +0000 (09:27 +0000)
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/SeqPanel.java
src/jalview/datamodel/HistoryItem.java [new file with mode: 0755]
src/jalview/gui/AlignFrame.java
src/jalview/gui/SeqPanel.java

index dd4ff38..0003d14 100755 (executable)
@@ -101,75 +101,94 @@ public class AlignFrame extends GAlignFrame
   Stack redoList = new Stack();\r
 \r
   void updateEditMenuBar()\r
-  {\r
-    if(historyList.size()>0)\r
+   {\r
+     if(historyList.size()>0)\r
+      {\r
+        undoMenuItem.setEnabled(true);\r
+        HistoryItem hi = (HistoryItem)historyList.peek();\r
+        undoMenuItem.setLabel("Undo "+hi.getDescription());\r
+      }\r
+     else\r
      {\r
-       undoMenuItem.setEnabled(true);\r
-       Object [] history = (Object[])historyList.elementAt(0);\r
-       undoMenuItem.setLabel("Undo "+history[0]);\r
+       undoMenuItem.setEnabled(false);\r
+       undoMenuItem.setLabel("Undo");\r
      }\r
-    else\r
-    {\r
-      undoMenuItem.setEnabled(false);\r
-      undoMenuItem.setLabel("Undo");\r
-    }\r
 \r
-    if(redoList.size()>0)\r
+     if(redoList.size()>0)\r
+      {\r
+        redoMenuItem.setEnabled(true);\r
+        HistoryItem hi = (HistoryItem)redoList.peek();\r
+        redoMenuItem.setLabel("Redo "+hi.getDescription());\r
+      }\r
+     else\r
      {\r
-       redoMenuItem.setEnabled(true);\r
-       Object [] history = (Object[])redoList.elementAt(0);\r
-       redoMenuItem.setLabel("Redo "+history[0]);\r
+       redoMenuItem.setEnabled(false);\r
+       redoMenuItem.setLabel("Redo");\r
      }\r
-    else\r
-    {\r
-      redoMenuItem.setEnabled(false);\r
-      redoMenuItem.setLabel("Redo");\r
-    }\r
-  }\r
+   }\r
 \r
-  public void addHistoryItem(String type)\r
-  {\r
-    // must make sure we add new sequence objects her, not refs to the existing sequences\r
-    redoList.removeAllElements();\r
-    SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
-    for(int i=0; i<viewport.getAlignment().getHeight(); i++)\r
-    {\r
-      seq[i] = new Sequence( viewport.getAlignment().getSequenceAt(i).getName(),\r
-                             viewport.getAlignment().getSequenceAt(i).getSequence());\r
-    }\r
+   public void addHistoryItem(HistoryItem hi)\r
+   {\r
+     historyList.push(hi);\r
+     updateEditMenuBar();\r
+   }\r
 \r
-    historyList.addElement(new Object[]{type,  seq} );\r
-    updateEditMenuBar();\r
-  }\r
+   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
+   {\r
+       HistoryItem hi = (HistoryItem)historyList.pop();\r
+       redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment, HistoryItem.HIDE));\r
+       restoreHistoryItem(hi);\r
+   }\r
 \r
-  protected void undoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-    Object [] history = (Object[])historyList.elementAt(0);\r
-    historyList.removeElementAt(0);\r
-    // add the redo state before continuing!!\r
-    SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
-    for (int i = 0; i < viewport.getAlignment().getHeight(); i++)\r
-    {\r
-      seq[i] = new Sequence(viewport.getAlignment().getSequenceAt(i).getName(),\r
-                            viewport.getAlignment().getSequenceAt(i).\r
-                            getSequence());\r
-    }\r
-    /////////\r
+   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
+   {\r
+      HistoryItem hi = (HistoryItem)redoList.pop();\r
+      restoreHistoryItem(hi);\r
+      updateEditMenuBar();\r
+      viewport.updateConsensus();\r
+      alignPanel.repaint();\r
+      alignPanel.repaint();\r
+   }\r
 \r
-    redoList.addElement(new Object[] {history[0], seq});\r
 \r
-      seq = (SequenceI[]) history[1];\r
+   // used by undo and redo\r
+   void restoreHistoryItem(HistoryItem hi)\r
+   {\r
+      if(hi.getType()== HistoryItem.SORT)\r
+      {\r
+           for(int i=0; i<hi.getSequences().size(); i++)\r
+             viewport.alignment.getSequences().setElementAt(hi.getSequences().elementAt(i), i);\r
+      }\r
+      else\r
+      {\r
+        for (int i = 0; i < hi.getSequences().size(); i++)\r
+        {\r
+          SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
+          if(restore.getLength()==0)\r
+          {\r
+            System.out.println(hi.getHidden().elementAt(i));\r
+            restore.setSequence(hi.getHidden().elementAt(i).toString());\r
+            viewport.alignment.getSequences().insertElementAt(\r
+               restore,\r
+               hi.getAlignIndex(i));\r
+          }\r
+          else\r
+            restore.setSequence(hi.getHidden().elementAt(i).toString());\r
+        }\r
+        if(hi.getType()==HistoryItem.PASTE)\r
+        {\r
+          for(int i=viewport.alignment.getHeight()-1;i>hi.getSequences().size()-1; i--)\r
+            viewport.alignment.deleteSequence(i);\r
+        }\r
+      }\r
 \r
-      AlignmentAnnotation[] old = viewport.alignment.getAlignmentAnnotation();\r
-      viewport.setAlignment(new Alignment(seq));\r
-      updateEditMenuBar();\r
-      for (int i = 0; i < old.length; i++)\r
-        viewport.alignment.addAnnotation(old[i]);\r
+       updateEditMenuBar();\r
+\r
+       viewport.updateConsensus();\r
+       viewport.updateConservation();\r
+       alignPanel.repaint();\r
+   }\r
 \r
-      viewport.updateConservation();\r
-      viewport.updateConsensus();\r
-      alignPanel.repaint();\r
-  }\r
 \r
   public void moveSelectedSequences(boolean up)\r
   {\r
@@ -261,7 +280,7 @@ public class AlignFrame extends GAlignFrame
 \r
   protected void pasteThis_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("Paste");\r
+    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment, HistoryItem.PASTE));\r
     paste(false);\r
   }\r
 \r
@@ -322,7 +341,7 @@ public class AlignFrame extends GAlignFrame
 \r
   protected void delete_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("Delete");\r
+    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment, HistoryItem.HIDE));\r
     if (viewport.getSelectionGroup() == null)\r
       return;\r
 \r
@@ -355,23 +374,6 @@ public class AlignFrame extends GAlignFrame
 \r
 \r
 \r
-  protected void redoMenuItem_actionPerformed(ActionEvent e)\r
-  {\r
-     Object [] history = (Object[])redoList.pop();\r
-     SequenceI[] seq = (SequenceI[]) history[1];\r
-\r
-     AlignmentAnnotation[] old = viewport.alignment.getAlignmentAnnotation();\r
-     viewport.setAlignment(new Alignment(seq));\r
-     for (int i = 0; i < old.length; i++)\r
-       viewport.alignment.addAnnotation(old[i]);\r
-\r
-     viewport.updateConservation();\r
-     viewport.updateConsensus();\r
-     updateEditMenuBar();\r
-     alignPanel.repaint();\r
-  }\r
-\r
-\r
   protected void deleteGroups_actionPerformed(ActionEvent e)\r
   {\r
     viewport.alignment.deleteAllGroups();\r
@@ -412,10 +414,11 @@ public class AlignFrame extends GAlignFrame
 \r
   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("delete columns");\r
     ColumnSelection colSel = viewport.getColumnSelection();\r
     if (colSel.size() > 0)\r
     {\r
+      addHistoryItem(new HistoryItem("Remove Left",viewport.alignment,\r
+                                     HistoryItem.HIDE));\r
       int min = colSel.getMin();\r
       viewport.getAlignment().trimLeft(min);\r
       colSel.compensateForEdit(0,min);\r
@@ -437,10 +440,11 @@ public class AlignFrame extends GAlignFrame
 \r
   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("delete columns");\r
     ColumnSelection colSel = viewport.getColumnSelection();\r
     if (colSel.size() > 0)\r
     {\r
+      addHistoryItem(new HistoryItem("Remove Right",viewport.alignment,\r
+                                     HistoryItem.HIDE));\r
       int max = colSel.getMax();\r
       viewport.getAlignment().trimRight(max);\r
       if(viewport.getSelectionGroup()!=null)\r
@@ -463,7 +467,9 @@ public class AlignFrame extends GAlignFrame
 \r
   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("delete gapped columns");\r
+    addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
+                                   viewport.alignment,\r
+                                   HistoryItem.HIDE));\r
     viewport.getAlignment().removeGaps();\r
     viewport.updateConservation();\r
     viewport.updateConsensus();\r
@@ -472,7 +478,9 @@ public class AlignFrame extends GAlignFrame
 \r
   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("delete all gaps");\r
+    addHistoryItem(new HistoryItem("Remove Gaps",\r
+                                   viewport.alignment,\r
+                                   HistoryItem.HIDE));\r
     SequenceI current;\r
     int jSize;\r
     for (int i=0; i < viewport.getAlignment().getSequences().size();i++)\r
@@ -860,21 +868,21 @@ public class AlignFrame extends GAlignFrame
 \r
   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("sort");\r
+    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment, HistoryItem.SORT));\r
     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));\r
     alignPanel.repaint();\r
   }\r
 \r
   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("sort");\r
+    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment, HistoryItem.SORT));\r
     AlignmentSorter.sortByID( viewport.getAlignment() );\r
     alignPanel.repaint();\r
   }\r
 \r
   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
   {\r
-    addHistoryItem("sort");\r
+    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment, HistoryItem.SORT));\r
     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
     AlignmentSorter.sortGroups(viewport.getAlignment());\r
     alignPanel.repaint();\r
@@ -976,7 +984,8 @@ public class AlignFrame extends GAlignFrame
     {\r
       public void actionPerformed(ActionEvent e)\r
       {\r
-        addHistoryItem("sort");\r
+        addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
+                                       HistoryItem.SORT));\r
         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
         alignPanel.repaint();\r
       }\r
index e6e02c5..27250cd 100755 (executable)
@@ -15,6 +15,8 @@ public class SeqPanel extends Panel
 \r
   protected int lastres;\r
   protected int startseq;\r
+  int startEdit=-1;\r
+  int endEdit=-1;\r
 \r
   protected AlignViewport av;\r
 \r
@@ -24,6 +26,10 @@ public class SeqPanel extends Panel
   ScrollThread scrollThread = null;\r
   boolean mouseDragging = false;\r
 \r
+  boolean editingSeqs = false;\r
+  boolean groupEditing = false;\r
+\r
+\r
 \r
   public SeqPanel(AlignViewport avp, AlignmentPanel p) {\r
     this.av         = avp;\r
@@ -46,7 +52,7 @@ public class SeqPanel extends Panel
       {\r
         if(av.getWrapAlignment())\r
          return;\r
-        if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        if( editingSeqs )\r
           doMouseDragged(evt);\r
         else\r
           doMouseDraggedDefineMode(evt);\r
@@ -59,32 +65,38 @@ public class SeqPanel extends Panel
       {\r
         if(av.getWrapAlignment())\r
          return;\r
-        if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        if(editingSeqs)\r
           doMouseReleased(evt);\r
         else\r
           doMouseReleasedDefineMode(evt);\r
+\r
       }\r
       public void mousePressed(MouseEvent evt)\r
       {\r
         if(av.getWrapAlignment())\r
          return;\r
+       System.out.println("here");\r
         if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        {\r
+          if(evt.isAltDown() || evt.isControlDown())\r
+            groupEditing = true;\r
+\r
+          editingSeqs = true;\r
           doMousePressed(evt);\r
+        }\r
         else\r
           doMousePressedDefineMode(evt);\r
       }\r
       public void mouseExited(MouseEvent evt)\r
       {\r
-        if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() ||\r
-                  evt.isControlDown())\r
+        if (av.getWrapAlignment() || editingSeqs)\r
                 return;\r
               doMouseExitedDefineMode(evt);\r
 \r
       }\r
       public void mouseEntered(MouseEvent evt)\r
       {\r
-        if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() ||\r
-            evt.isControlDown())\r
+        if (av.getWrapAlignment() || editingSeqs)\r
           return;\r
         doMouseEnteredDefineMode(evt);\r
       }\r
@@ -96,18 +108,20 @@ public class SeqPanel extends Panel
 \r
   public void doMouseReleased(MouseEvent evt) {\r
 \r
-    startseq = -1;\r
-    lastres  = -1;\r
     if(seqEditOccurred>-1)\r
-      updateConservation(seqEditOccurred);\r
+      editOccurred(seqEditOccurred);\r
 \r
+    startseq = -1;\r
+    lastres  = -1;\r
     seqEditOccurred = -1;\r
-\r
+    editingSeqs  = false;\r
+    groupEditing = false;\r
     ap.repaint();\r
   }\r
 \r
   public void doMousePressed(MouseEvent evt) {\r
-    ap.alignFrame.addHistoryItem("sequence edit");\r
+    ap.alignFrame.addHistoryItem( new HistoryItem(\r
+        "Edit Sequence",av.alignment, HistoryItem.EDIT));\r
     int seq;\r
     int res;\r
 \r
@@ -221,98 +235,107 @@ public class SeqPanel extends Panel
 \r
 \r
       if (res != lastres)\r
-      {\r
-          // Group editing\r
-          if (evt.isAltDown() || evt.isControlDown())\r
-          {\r
-            SequenceGroup sg = av.getSelectionGroup();\r
-            if(sg==null)\r
-            {\r
-              lastres=-1;\r
-              return;\r
-            }\r
-\r
-              // drag to right\r
-              if(dragRight)\r
-                  sg.setEndRes(sg.getEndRes() + (res-lastres));\r
-\r
-              // drag to left\r
-              else\r
-              {\r
-                 /// Are we able to delete?\r
-                 // ie are all columns blank?\r
-                 boolean deleteAllowed = false;\r
-                for (int s = 0; s < sg.getSize(); s++)\r
-                {\r
-                  SequenceI seq = sg.getSequenceAt(s);\r
-                  for (int j=res; j<lastres; j++)\r
-                  {\r
-                    if(seq.getSequence().length()<=j)\r
-                      continue;\r
-\r
-                    if(!jalview.util.Comparison.isGap(seq.getSequence().charAt(j)))\r
-                    {\r
-                      // Not a gap, block edit not valid\r
-                      res=j+1;\r
-                      deleteAllowed = false;\r
-                      continue;\r
-                    }\r
-                    deleteAllowed = true;\r
-                  }\r
-                }\r
-\r
-                if(!deleteAllowed)\r
-                {\r
-                  lastres = -1;\r
-                  return;\r
-                }\r
-\r
-                sg.setEndRes(sg.getEndRes() - (lastres-res));\r
-              }\r
-\r
-\r
-              for (int i = 0; i < sg.getSize(); i++)\r
-              {\r
-                SequenceI s = sg.getSequenceAt(i);\r
-                int k = av.alignment.findIndex(s);\r
-\r
-                // drag to right\r
-                if (dragRight)\r
-                  for (int j = lastres; j < res; j++)\r
-                    insertChar(j, k);\r
-\r
-                // drag to left\r
-                else\r
-                {\r
-                  for (int j = res; j < lastres; j++)\r
-                  {\r
-                    if(s.getLength()>j)\r
-                      deleteChar(res, k);\r
-                  }\r
-                }\r
-              }\r
-          }\r
-          else /////Editing a single sequence///////////\r
-          {\r
-            if (res < av.getAlignment().getWidth() && res > lastres)\r
-            {\r
-              // dragging to the right\r
-              for (int j = lastres; j < res; j++)\r
-                insertChar(j, startseq);\r
-            }\r
-            else if (res < av.getAlignment().getWidth() && res < lastres)\r
-            {\r
-              // dragging to the left\r
-              for (int j = lastres; j > res; j--)\r
-              {\r
-                deleteChar(res, startseq);\r
-              }\r
-            }\r
-\r
-          }\r
-      }\r
+     {\r
+         // Group editing\r
+         if (groupEditing)\r
+         {\r
+           SequenceGroup sg = av.getSelectionGroup();\r
+           if(sg==null)\r
+           {\r
+             lastres=-1;\r
+             return;\r
+           }\r
 \r
-      lastres = res;\r
+             // drag to right\r
+             if(dragRight)\r
+                 sg.setEndRes(sg.getEndRes() + (res-lastres));\r
+\r
+             // drag to left\r
+             else\r
+             {\r
+                /// Are we able to delete?\r
+                // ie are all columns blank?\r
+                boolean deleteAllowed = false;\r
+               for (int s = 0; s < sg.getSize(); s++)\r
+               {\r
+                 SequenceI seq = sg.getSequenceAt(s);\r
+                 for (int j=res; j<lastres; j++)\r
+                 {\r
+                   if(seq.getSequence().length()<=j)\r
+                     continue;\r
+\r
+                   if(!jalview.util.Comparison.isGap(seq.getSequence().charAt(j)))\r
+                   {\r
+                     // Not a gap, block edit not valid\r
+                     res=j+1;\r
+                     deleteAllowed = false;\r
+                     continue;\r
+                   }\r
+                   deleteAllowed = true;\r
+                 }\r
+               }\r
+\r
+               if(!deleteAllowed)\r
+               {\r
+                 lastres = -1;\r
+                 return;\r
+               }\r
+\r
+               sg.setEndRes(sg.getEndRes() - (lastres-res));\r
+             }\r
+\r
+\r
+             for (int i = 0; i < sg.getSize(); i++)\r
+             {\r
+               SequenceI s = sg.getSequenceAt(i);\r
+               int k = av.alignment.findIndex(s);\r
+\r
+               // drag to right\r
+               if (dragRight)\r
+                 for (int j = lastres; j < res; j++)\r
+                   insertChar(j, k);\r
+\r
+               // drag to left\r
+               else\r
+               {\r
+                 for (int j = res; j < lastres; j++)\r
+                 {\r
+                   if(s.getLength()>j)\r
+                     deleteChar(res, k);\r
+                 }\r
+               }\r
+             }\r
+         }\r
+         else /////Editing a single sequence///////////\r
+         {\r
+           if (res < av.getAlignment().getWidth() && res > lastres)\r
+           {\r
+             // dragging to the right\r
+             for (int j = lastres; j < res; j++)\r
+               insertChar(j, startseq);\r
+           }\r
+           else if (res < av.getAlignment().getWidth() && res < lastres)\r
+           {\r
+             // dragging to the left\r
+             for (int j = lastres; j > res; j--)\r
+             {\r
+               if( jalview.util.Comparison.isGap(\r
+                 av.alignment.getSequenceAt(startseq).getSequence().charAt(res)))\r
+\r
+               deleteChar(res, startseq);\r
+               else\r
+               {\r
+\r
+                 break;\r
+               }\r
+             }\r
+           }\r
+\r
+         }\r
+     }\r
+\r
+     endEdit = res;\r
+     lastres = res;\r
       seqCanvas.repaint();\r
   }\r
 \r
@@ -330,17 +353,21 @@ public class SeqPanel extends Panel
   public void deleteChar(int j, int seq)\r
   {\r
 \r
-    if ( jalview.util.Comparison.isGap( av.alignment.getSequenceAt(seq).getSequence().charAt(j)))\r
-      av.alignment.getSequenceAt(seq).deleteCharAt(j);\r
-\r
+    av.alignment.getSequenceAt(seq).deleteCharAt(j);\r
+    seqEditOccurred=seq;\r
     av.alignment.getWidth();\r
     repaint();\r
-    seqEditOccurred=seq;\r
   }\r
 \r
 \r
-  void updateConservation(int i)\r
+  void editOccurred(int i)\r
   {\r
+    if(endEdit==startEdit)\r
+    {\r
+      ap.alignFrame.historyList.pop();\r
+      ap.alignFrame.updateEditMenuBar();\r
+    }\r
+\r
     av.updateConservation();\r
     av.updateConsensus();\r
 \r
@@ -352,6 +379,7 @@ public class SeqPanel extends Panel
       cs = new ClustalxColourScheme(av.alignment.getSequences(), av.alignment.getWidth());\r
 \r
     ap.alignFrame.changeColour(cs);\r
+\r
   }\r
 \r
 //////////////////////////////////////////\r
diff --git a/src/jalview/datamodel/HistoryItem.java b/src/jalview/datamodel/HistoryItem.java
new file mode 100755 (executable)
index 0000000..3a5b180
--- /dev/null
@@ -0,0 +1,52 @@
+package jalview.datamodel;\r
+\r
+import java.util.*;\r
+\r
+public class HistoryItem\r
+{\r
+  public static final int EDIT = 0;\r
+  public static final int SORT = 1;\r
+  public static final int HIDE = 2;\r
+  public static final int PASTE= 3;\r
+\r
+  final int type;\r
+  Vector sequences;\r
+  Vector alignIndex;\r
+  String description;\r
+  Vector hiddenSeqs;\r
+\r
+  public HistoryItem(String description, AlignmentI al, int type)\r
+  {\r
+    this.type = type;\r
+    this.description = description;\r
+    sequences = new Vector();\r
+    alignIndex = new Vector();\r
+    hiddenSeqs = new Vector();\r
+\r
+    for (int i = 0; i < al.getHeight(); i++)\r
+    {\r
+      SequenceI seq = al.getSequenceAt(i);\r
+      sequences.addElement(seq);\r
+      alignIndex.addElement(i + "");\r
+      hiddenSeqs.addElement(seq.getSequence().toString());\r
+    }\r
+  }\r
+\r
+  public int getType()\r
+  {return type;}\r
+\r
+  public Vector getSequences()\r
+  {return sequences;}\r
+\r
+  public String getDescription()\r
+  {return description; }\r
+\r
+  public Vector getHidden()\r
+  { return hiddenSeqs; }\r
+\r
+  public int getAlignIndex(int seq)\r
+  {\r
+    return Integer.parseInt(alignIndex.elementAt(seq).toString());\r
+  }\r
+\r
+}\r
index b60ee62..63b3787 100755 (executable)
@@ -171,75 +171,94 @@ public class AlignFrame extends GAlignFrame
   Stack redoList = new Stack();
 
   void updateEditMenuBar()
-  {
-    if(historyList.size()>0)
+   {
+     if(historyList.size()>0)
+      {
+        undoMenuItem.setEnabled(true);
+        HistoryItem hi = (HistoryItem)historyList.peek();
+        undoMenuItem.setText("Undo "+hi.getDescription());
+      }
+     else
      {
-       undoMenuItem.setEnabled(true);
-       Object [] history = (Object[])historyList.get(0);
-       undoMenuItem.setText("Undo "+history[0]);
+       undoMenuItem.setEnabled(false);
+       undoMenuItem.setText("Undo");
      }
-    else
-    {
-      undoMenuItem.setEnabled(false);
-      undoMenuItem.setText("Undo");
-    }
 
-    if(redoList.size()>0)
+     if(redoList.size()>0)
+      {
+        redoMenuItem.setEnabled(true);
+        HistoryItem hi = (HistoryItem)redoList.peek();
+        redoMenuItem.setText("Redo "+hi.getDescription());
+      }
+     else
      {
-       redoMenuItem.setEnabled(true);
-       Object [] history = (Object[])redoList.get(0);
-       redoMenuItem.setText("Redo "+history[0]);
+       redoMenuItem.setEnabled(false);
+       redoMenuItem.setText("Redo");
      }
-    else
-    {
-      redoMenuItem.setEnabled(false);
-      redoMenuItem.setText("Redo");
-    }
-  }
-
-  public void addHistoryItem(String type)
-  {
-    // must make sure we add new sequence objects her, not refs to the existing sequences
-    redoList.clear();
-
-    SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];
-    for(int i=0; i<viewport.getAlignment().getHeight(); i++)
-    {
-      seq[i] = new Sequence( viewport.getAlignment().getSequenceAt(i).getName(),
-                             viewport.getAlignment().getSequenceAt(i).getSequence());
-    }
-
+   }
 
-    historyList.add(0, new Object[]{type,  seq} );
-    updateEditMenuBar();
-  }
+   public void addHistoryItem(HistoryItem hi)
+   {
+     historyList.push(hi);
+     updateEditMenuBar();
+   }
 
-  protected void undoMenuItem_actionPerformed(ActionEvent e)
-  {
-    Object [] history = (Object[])historyList.remove(0);
-    // add the redo state before continuing!!
-    SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];
-    for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
-    {
-      seq[i] = new Sequence(viewport.getAlignment().getSequenceAt(i).getName(),
-                            viewport.getAlignment().getSequenceAt(i).
-                            getSequence());
-    }
-    /////////
+   protected void undoMenuItem_actionPerformed(ActionEvent e)
+   {
+       HistoryItem hi = (HistoryItem)historyList.pop();
+       redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment, HistoryItem.HIDE));
+       restoreHistoryItem(hi);
+   }
 
-    redoList.add(0, new Object[] {history[0], seq});
 
-      seq = (SequenceI[]) history[1];
-      AlignmentAnnotation [] old = viewport.alignment.getAlignmentAnnotation();
-      viewport.setAlignment( new Alignment(seq) );
-      viewport.alignment.setGapCharacter( Preferences.gapSymbol );
+   protected void redoMenuItem_actionPerformed(ActionEvent e)
+   {
+      HistoryItem hi = (HistoryItem)redoList.pop();
+      restoreHistoryItem(hi);
       updateEditMenuBar();
-      for(int i=0; i<old.length; i++)
-        viewport.alignment.addAnnotation(old[i]);
       viewport.updateConsensus();
-      viewport.updateConservation();
       alignPanel.repaint();
-  }
+      alignPanel.repaint();
+   }
+
+
+   // used by undo and redo
+   void restoreHistoryItem(HistoryItem hi)
+   {
+      if(hi.getType()== HistoryItem.SORT)
+      {
+           for(int i=0; i<hi.getSequences().size(); i++)
+             viewport.alignment.getSequences().setElementAt(hi.getSequences().elementAt(i), i);
+      }
+      else
+      {
+        for (int i = 0; i < hi.getSequences().size(); i++)
+        {
+          SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);
+          if(restore.getLength()==0)
+          {
+            System.out.println(hi.getHidden().elementAt(i));
+            restore.setSequence(hi.getHidden().elementAt(i).toString());
+            viewport.alignment.getSequences().insertElementAt(
+               restore,
+               hi.getAlignIndex(i));
+          }
+          else
+            restore.setSequence(hi.getHidden().elementAt(i).toString());
+        }
+        if(hi.getType()==HistoryItem.PASTE)
+        {
+          for(int i=viewport.alignment.getHeight()-1;i>hi.getSequences().size()-1; i--)
+            viewport.alignment.deleteSequence(i);
+        }
+      }
+
+       updateEditMenuBar();
+
+       viewport.updateConsensus();
+       viewport.updateConservation();
+       alignPanel.repaint();
+   }
 
   public void moveSelectedSequences(boolean up)
   {
@@ -335,7 +354,7 @@ public class AlignFrame extends GAlignFrame
 
   protected void pasteThis_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("Paste");
+    addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment, HistoryItem.PASTE));
     paste(false);
   }
 
@@ -398,7 +417,8 @@ public class AlignFrame extends GAlignFrame
 
   protected void delete_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("Delete");
+    addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment, HistoryItem.HIDE));
+
     if (viewport.getSelectionGroup() == null)
       return;
 
@@ -430,20 +450,6 @@ public class AlignFrame extends GAlignFrame
   }
 
 
-
-  protected void redoMenuItem_actionPerformed(ActionEvent e)
-  {
-     Object [] history = (Object[])redoList.remove(0);
-     SequenceI[] seq = (SequenceI[]) history[1];
-     viewport.setAlignment( new Alignment(seq) );
-     viewport.alignment.setGapCharacter( Preferences.gapSymbol );
-     updateEditMenuBar();
-     viewport.updateConsensus();
-     alignPanel.repaint();
-     alignPanel.repaint();
-  }
-
-
   protected void deleteGroups_actionPerformed(ActionEvent e)
   {
     viewport.alignment.deleteAllGroups();
@@ -482,10 +488,11 @@ public class AlignFrame extends GAlignFrame
 
   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("delete columns");
     ColumnSelection colSel = viewport.getColumnSelection();
     if (colSel.size() > 0)
     {
+      addHistoryItem(new HistoryItem("Remove Left",viewport.alignment,
+                                     HistoryItem.HIDE));
       int min = colSel.getMin();
       viewport.getAlignment().trimLeft(min);
       colSel.compensateForEdit(0,min);
@@ -507,10 +514,12 @@ public class AlignFrame extends GAlignFrame
 
   public void remove2RightMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("delete columns");
     ColumnSelection colSel = viewport.getColumnSelection();
     if (colSel.size() > 0)
     {
+      addHistoryItem(new HistoryItem("Remove Right",viewport.alignment,
+                                     HistoryItem.HIDE));
+
       int max = colSel.getMax();
       viewport.getAlignment().trimRight(max);
       if(viewport.getSelectionGroup()!=null)
@@ -533,7 +542,9 @@ public class AlignFrame extends GAlignFrame
 
   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("delete gapped columns");
+    addHistoryItem(new HistoryItem("Remove Gapped Columns",
+                                   viewport.alignment,
+                                   HistoryItem.HIDE));
     viewport.getAlignment().removeGaps();
     viewport.updateConservation();
     viewport.updateConsensus();
@@ -542,7 +553,9 @@ public class AlignFrame extends GAlignFrame
 
   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("delete all gaps");
+    addHistoryItem(new HistoryItem("Remove Gaps",
+                                   viewport.alignment,
+                                   HistoryItem.HIDE));
     SequenceI current;
     int jSize;
     for (int i=0; i < viewport.getAlignment().getSequences().size();i++)
@@ -936,21 +949,21 @@ public class AlignFrame extends GAlignFrame
 
   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("sort");
+    addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment, HistoryItem.SORT));
     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));
     alignPanel.repaint();
   }
 
   public void sortIDMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("sort");
+    addHistoryItem(new HistoryItem("ID Sort", viewport.alignment, HistoryItem.SORT));
     AlignmentSorter.sortByID( viewport.getAlignment() );
     alignPanel.repaint();
   }
 
   public void sortGroupMenuItem_actionPerformed(ActionEvent e)
   {
-    addHistoryItem("sort");
+    addHistoryItem(new HistoryItem("Group Sort", viewport.alignment, HistoryItem.SORT));
     AlignmentSorter.sortByGroup(viewport.getAlignment());
     AlignmentSorter.sortGroups(viewport.getAlignment());
     alignPanel.repaint();
@@ -1061,7 +1074,8 @@ public class AlignFrame extends GAlignFrame
     {
       public void actionPerformed(ActionEvent e)
       {
-        addHistoryItem("sort");
+        addHistoryItem(new HistoryItem("Sort", viewport.alignment,
+                                       HistoryItem.SORT));
         // TODO: JBPNote - have to map order entries to curent SequenceI pointers
         AlignmentSorter.sortBy(viewport.getAlignment(), order);
         alignPanel.repaint();
@@ -1077,7 +1091,8 @@ public class AlignFrame extends GAlignFrame
     {
       public void actionPerformed(ActionEvent e)
       {
-        addHistoryItem("sort");
+        addHistoryItem(new HistoryItem("Tree Sort", viewport.alignment,
+                                       HistoryItem.SORT));
         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());
         alignPanel.repaint();
       }
index c43acf9..ca09c97 100755 (executable)
@@ -15,6 +15,8 @@ public class SeqPanel extends JPanel
 \r
   protected int lastres;\r
   protected int startseq;\r
+  int startEdit=-1;\r
+  int endEdit=-1;\r
 \r
   protected AlignViewport av;\r
 \r
@@ -24,6 +26,9 @@ public class SeqPanel extends JPanel
   ScrollThread scrollThread = null;\r
   boolean mouseDragging = false;\r
 \r
+  boolean editingSeqs = false;\r
+  boolean groupEditing = false;\r
+\r
 \r
   public SeqPanel(AlignViewport avp, AlignmentPanel p) {\r
     this.av         = avp;\r
@@ -46,7 +51,7 @@ public class SeqPanel extends JPanel
       {\r
         if(av.getWrapAlignment())\r
          return;\r
-        if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        if( editingSeqs )\r
           doMouseDragged(evt);\r
         else\r
           doMouseDraggedDefineMode(evt);\r
@@ -59,32 +64,37 @@ public class SeqPanel extends JPanel
       {\r
         if(av.getWrapAlignment())\r
          return;\r
-        if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        if(editingSeqs)\r
           doMouseReleased(evt);\r
         else\r
           doMouseReleasedDefineMode(evt);\r
+\r
       }\r
       public void mousePressed(MouseEvent evt)\r
       {\r
         if(av.getWrapAlignment())\r
          return;\r
         if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())\r
+        {\r
+          if(evt.isAltDown() || evt.isControlDown())\r
+            groupEditing = true;\r
+\r
+          editingSeqs = true;\r
           doMousePressed(evt);\r
+        }\r
         else\r
           doMousePressedDefineMode(evt);\r
       }\r
       public void mouseExited(MouseEvent evt)\r
       {\r
-        if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() ||\r
-                  evt.isControlDown())\r
+        if (av.getWrapAlignment() || editingSeqs)\r
                 return;\r
               doMouseExitedDefineMode(evt);\r
 \r
       }\r
       public void mouseEntered(MouseEvent evt)\r
       {\r
-        if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() ||\r
-            evt.isControlDown())\r
+        if (av.getWrapAlignment() || editingSeqs)\r
           return;\r
         doMouseEnteredDefineMode(evt);\r
       }\r
@@ -96,18 +106,23 @@ public class SeqPanel extends JPanel
 \r
   public void doMouseReleased(MouseEvent evt) {\r
 \r
-    startseq = -1;\r
-    lastres  = -1;\r
     if(seqEditOccurred>-1)\r
-      updateConservation(seqEditOccurred);\r
+      editOccurred(seqEditOccurred);\r
 \r
+    startseq = -1;\r
+    lastres  = -1;\r
     seqEditOccurred = -1;\r
+    editingSeqs  = false;\r
+    groupEditing = false;\r
 \r
     ap.repaint();\r
   }\r
 \r
   public void doMousePressed(MouseEvent evt) {\r
-    ap.alignFrame.addHistoryItem("sequence edit");\r
+\r
+    ap.alignFrame.addHistoryItem( new HistoryItem(\r
+        "Edit Sequence",av.alignment, HistoryItem.EDIT));\r
+\r
     int seq;\r
     int res;\r
 \r
@@ -120,14 +135,8 @@ public class SeqPanel extends JPanel
     if (seq < av.getAlignment().getHeight() &&\r
         res < av.getAlignment().getSequenceAt(seq).getLength())\r
     {\r
-      //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);\r
-      // Find the residue's position in the sequence (res is the position\r
-      // in the alignment\r
-\r
       startseq = seq;\r
-\r
       lastres = res;\r
-\r
     }\r
     else\r
     {\r
@@ -135,6 +144,9 @@ public class SeqPanel extends JPanel
       lastres = -1;\r
     }\r
 \r
+    startEdit = lastres;\r
+    endEdit = lastres;\r
+\r
     return;\r
   }\r
 \r
@@ -227,10 +239,10 @@ public class SeqPanel extends JPanel
 \r
     if (res != lastres)\r
     {\r
-       // Group editing\r
-       if (evt.isAltDown() || evt.isControlDown())\r
+        // Group editing\r
+        if (groupEditing)\r
         {\r
-         SequenceGroup sg = av.getSelectionGroup();\r
+          SequenceGroup sg = av.getSelectionGroup();\r
           if(sg==null)\r
           {\r
             lastres=-1;\r
@@ -310,13 +322,22 @@ public class SeqPanel extends JPanel
             // dragging to the left\r
             for (int j = lastres; j > res; j--)\r
             {\r
+              if( jalview.util.Comparison.isGap(\r
+                av.alignment.getSequenceAt(startseq).getSequence().charAt(res)))\r
+\r
               deleteChar(res, startseq);\r
+              else\r
+              {\r
+\r
+                break;\r
+              }\r
             }\r
-         }\r
+          }\r
 \r
-       }\r
+        }\r
     }\r
 \r
+    endEdit = res;\r
     lastres = res;\r
     repaint();\r
   }\r
@@ -334,21 +355,22 @@ public class SeqPanel extends JPanel
 \r
   public void deleteChar(int j, int seq)\r
   {\r
+    av.alignment.getSequenceAt(seq).deleteCharAt(j);\r
+    seqEditOccurred=seq;\r
 \r
-    if ( jalview.util.Comparison.isGap( av.alignment.getSequenceAt(seq).getSequence().charAt(j)))\r
-    {  av.alignment.getSequenceAt(seq).deleteCharAt(j);\r
-\r
-    }\r
-    else System.out.println("err "+seq+" "+j);\r
     av.alignment.getWidth();\r
     repaint();\r
-    seqEditOccurred=seq;\r
-\r
   }\r
 \r
 \r
-  void updateConservation(int i)\r
+  void editOccurred(int i)\r
   {\r
+    if(endEdit==startEdit)\r
+    {\r
+      ap.alignFrame.historyList.pop();\r
+      ap.alignFrame.updateEditMenuBar();\r
+    }\r
+\r
     av.updateConservation();\r
     av.updateConsensus();\r
 \r
@@ -440,6 +462,7 @@ public class SeqPanel extends JPanel
       // Edit end res position of selected group\r
       changeStartRes = true;\r
 \r
+    stretchGroup.getWidth();\r
 \r
     repaint();\r
 \r