End of GroupEditing, GroupDefiningMode!!!!!
[jalview.git] / src / jalview / gui / SeqPanel.java
1 package jalview.gui;\r
2 \r
3 import java.awt.*;\r
4 import java.awt.event.*;\r
5 import jalview.datamodel.*;\r
6 import javax.swing.*;\r
7 import jalview.schemes.*;\r
8 import jalview.analysis.*;\r
9 \r
10 \r
11 public class SeqPanel extends JPanel\r
12 {\r
13 \r
14   public    SeqCanvas         seqCanvas;\r
15   public    AlignmentPanel    parent;\r
16 \r
17   protected int startres;\r
18   protected int lastres;\r
19   protected int endres;\r
20 \r
21   protected int startseq;\r
22   protected int padseq;\r
23 \r
24   public    boolean editFlag;\r
25   protected AlignViewport av;\r
26 \r
27   // if character is inserted or deleted, we will need to recalculate the conservation\r
28   int seqEditOccurred = -1;\r
29 \r
30   public SeqPanel(AlignViewport avp, AlignmentPanel p) {\r
31     this.av         = avp;\r
32 \r
33     seqCanvas  = new SeqCanvas(avp);\r
34     setLayout(new BorderLayout());\r
35     add(seqCanvas, BorderLayout.CENTER);\r
36 \r
37     parent = p;\r
38 \r
39     addMouseMotionListener( new MouseMotionAdapter()\r
40     {\r
41       public void mouseMoved(MouseEvent evt)\r
42       {   doMouseMoved(evt);    }\r
43 \r
44       public void mouseDragged(MouseEvent evt)\r
45       {\r
46         if(evt.isShiftDown() || evt.isControlDown())\r
47           doMouseDragged(evt);\r
48         else\r
49           doMouseDraggedDefineMode(evt);\r
50       }\r
51     });\r
52 \r
53     addMouseListener( new MouseAdapter()\r
54     {\r
55       public void mouseReleased(MouseEvent evt)\r
56       {\r
57         if(evt.isShiftDown() || evt.isControlDown())\r
58           doMouseReleased(evt);\r
59         else\r
60           doMouseReleasedDefineMode(evt);\r
61       }\r
62       public void mousePressed(MouseEvent evt)\r
63       {\r
64         if(evt.isShiftDown() || evt.isControlDown())\r
65           doMousePressed(evt);\r
66         else\r
67           doMousePressedDefineMode(evt);\r
68       }\r
69 \r
70     });\r
71     repaint();\r
72   }\r
73 \r
74 \r
75   public void doMouseReleased(MouseEvent evt) {\r
76 \r
77     int x = evt.getX();\r
78     int res = x/av.getCharWidth() + av.getStartRes();\r
79 \r
80     endres = res;\r
81 \r
82       // This is to detect edits - we're at the end of an edit if mouse is up\r
83     editFlag = false;\r
84     startseq = -1;\r
85     startres = -1;\r
86     lastres  = -1;\r
87     if(seqEditOccurred>-1)\r
88       updateConservation(seqEditOccurred);\r
89 \r
90     seqEditOccurred = -1;\r
91 \r
92     parent.RefreshPanels();\r
93     repaint();\r
94 \r
95   }\r
96 \r
97   public void doMousePressed(MouseEvent evt) {\r
98     parent.alignFrame.addHistoryItem("sequence edit");\r
99     int seq;\r
100     int res;\r
101 \r
102     int x = evt.getX();\r
103     int y = evt.getY();\r
104 \r
105     res = x/av.getCharWidth() + av.getStartRes();\r
106     seq = y/av.getCharHeight() + av.getStartSeq();\r
107 \r
108     if (seq < av.getAlignment().getHeight() && res < av.getAlignment().getSequenceAt(seq).getLength())\r
109     {\r
110       //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);\r
111       // Find the residue's position in the sequence (res is the position\r
112       // in the alignment\r
113 \r
114       startseq = seq;\r
115 \r
116       if (startseq == (av.getAlignment().getHeight()-1)) {\r
117         padseq = 1;\r
118       } else {\r
119         padseq = 1;\r
120       }\r
121 \r
122       startres = res;\r
123       lastres = res;\r
124 \r
125       } else {\r
126       startseq = -1;\r
127       startres = -1;\r
128       lastres = -1;\r
129     }\r
130 \r
131     return;\r
132   }\r
133 \r
134   public void doMouseMoved(MouseEvent evt)\r
135   {\r
136     int res=0, seq=0;\r
137     int x = evt.getX();\r
138     int y = evt.getY();\r
139     if(av.wrapAlignment)\r
140     {\r
141       y -= 2*av.charHeight;\r
142       int chunkHeight = (av.getAlignment().getHeight()+2)*av.charHeight;\r
143 \r
144 \r
145       res =   (int)((y/chunkHeight)*(getWidth()/av.charWidth)) +  x/av.getCharWidth() + av.getStartRes();\r
146 \r
147       y %= chunkHeight;\r
148       seq =     y / av.getCharHeight() + av.getStartSeq();\r
149 \r
150       //   chunkHeight =  (da.getHeight() + 2)*charHeight;\r
151       //  startx += chunkWidth;\r
152     }\r
153     else\r
154     {\r
155       res = x / av.getCharWidth()  + av.getStartRes();\r
156       seq = y / av.getCharHeight() + av.getStartSeq();\r
157     }\r
158 \r
159 \r
160     if(seq>=av.getAlignment().getHeight())\r
161       return;\r
162 \r
163     Object obj = ResidueProperties.aa2Triplet.get( av.getAlignment().getSequenceAt(seq).getCharAt(res)+"" ) ;\r
164     String aa = "";\r
165     if(obj!=null)\r
166          aa = obj.toString();\r
167 \r
168     StringBuffer text = new StringBuffer("Sequence " +(seq+1)+" ID: "+av.getAlignment().getSequenceAt(seq).getName());\r
169     if(aa!="")\r
170       text.append("  Residue: "+aa+" ("+  av.getAlignment().getSequenceAt(seq).findPosition(res)+")");\r
171 \r
172     parent.alignFrame.statusBar.setText(text.toString());\r
173 \r
174   }\r
175 \r
176   public void doMouseDragged(MouseEvent evt) {\r
177     // If we're dragging we're editing\r
178 \r
179     editFlag = true;\r
180     int x = evt.getX();\r
181 \r
182     int res = x/av.getCharWidth() + av.getStartRes();\r
183     if (res < 0) {res = 0;}\r
184 \r
185     if (res  != lastres) {\r
186       if (startseq != -1) {\r
187 \r
188         // Group editing\r
189         if (evt.isControlDown()) {\r
190           SequenceGroup sg = av.getAlignment().findGroup(startseq);\r
191 \r
192           if(sg!=null)\r
193           if (res < av.getAlignment().getWidth() && res < lastres)\r
194           {\r
195             boolean flag = false;\r
196             for (int i= 0 ; i < sg.getSize(); i++)\r
197             {\r
198               SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
199               for (int j=lastres-1; j >= res; j--)\r
200               {\r
201                 if (!flag)\r
202                 {\r
203                   if (s.getSequence().charAt(j)!=av.getAlignment().getGapCharacter() &&\r
204                       s.getSequence().charAt(j)==' ')\r
205                   {\r
206                     res = j+1;\r
207                     flag = true;\r
208                   }\r
209                 }\r
210               }\r
211             }\r
212           }\r
213 \r
214           if(sg!=null)\r
215           for (int i= 0 ; i < sg.getSize(); i++)\r
216           {\r
217             SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
218             boolean found = false;\r
219             int sno = -1;\r
220             for (int k = 0; k < av.getAlignment().getHeight(); k++)\r
221             {\r
222               if (av.getAlignment().getSequenceAt(k) == s)\r
223               {\r
224                 found = true;\r
225                 sno = k;\r
226                 break;\r
227               }\r
228             }\r
229             if (found && sno != -1) {\r
230               if (res < av.getAlignment().getWidth() && res > lastres)\r
231               {\r
232                 for (int j = lastres; j < res; j++)\r
233                   insertChar(j,sno);\r
234 \r
235                 int index = av.getAlignment().findIndex(s);\r
236                 if (index != -1)\r
237                   drawChars(index,index+1,lastres);\r
238 \r
239 \r
240               } else if (res < av.getAlignment().getWidth() && res < lastres)\r
241               {\r
242                 for (int j = res; j < lastres; j++)\r
243                 {\r
244                   deleteChar(j,res,sno);\r
245                   startres = res;\r
246                 }\r
247                 int index = av.getAlignment().findIndex(s);\r
248                 if (index != -1)\r
249                   drawChars(index,index+1,res);\r
250 \r
251               }\r
252             }\r
253 \r
254           }\r
255           lastres = res;\r
256         } else {\r
257 \r
258 \r
259           if (res < av.getAlignment().getWidth() && res > lastres) {\r
260             // dragging to the right\r
261             for (int j = lastres; j < res; j++)\r
262               insertChar(j,startseq);\r
263 \r
264             drawChars(startseq,startseq+1,lastres);\r
265 \r
266           } else if (res < av.getAlignment().getWidth() && res < lastres)\r
267           {\r
268 \r
269             // dragging to the left\r
270             for (int j = res; j < lastres; j++) {\r
271               deleteChar(j,res,startseq);\r
272               startres = res;\r
273             }\r
274             drawChars(startseq,startseq+1,res);\r
275           }\r
276         }\r
277       }\r
278       lastres = res;\r
279     }\r
280 \r
281     repaint();\r
282     return;\r
283   }\r
284 \r
285   public void drawChars(int seqstart, int seqend, int start) {\r
286     seqCanvas.drawPanel(seqCanvas.gg, start,av.getEndRes(),seqstart,seqend,av.getStartRes(),av.getStartSeq(),0);\r
287     repaint();\r
288   }\r
289 \r
290   public void insertChar(int j, int seq)\r
291   {\r
292     av.getAlignment().getSequenceAt(seq).insertCharAt(j, av.getGapCharacter());\r
293     seqEditOccurred=seq;\r
294   }\r
295 \r
296   public void deleteChar(int j, int res, int seq)\r
297   {\r
298 \r
299     if (av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='.' ||\r
300         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='-' ||\r
301         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)==' ' )\r
302     {\r
303         av.getAlignment().getSequenceAt(seq).deleteCharAt(j);\r
304     }\r
305 \r
306     av.getAlignment().getWidth();\r
307     repaint();\r
308     seqEditOccurred=seq;\r
309   }\r
310 \r
311 \r
312   void updateConservation(int i)\r
313   {\r
314   /*  Alignment al = (Alignment) av.getAlignment();\r
315     SequenceGroup sg = av.alignment.findGroup( al.getSequenceAt(i));\r
316     if(sg==null || !(sg.cs instanceof ConservationColourScheme))\r
317       return;\r
318 \r
319     Conservation c = sg.getConservation();\r
320 \r
321     c = new Conservation("All", al.cons,\r
322                          ResidueProperties.propHash, 3, sg.sequences, 0,\r
323                          al.getWidth());\r
324     c.calculate();\r
325     c.verdict(false, 100);\r
326     sg.setConservation(c);\r
327     ConservationColourScheme ccs = (ConservationColourScheme)sg.cs;\r
328     ccs.conserve = c;*/\r
329   }\r
330 \r
331   int oldSeq = -1;\r
332 \r
333   public void doMousePressedDefineMode(MouseEvent evt)\r
334   {\r
335     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
336     int seq = evt.getY()/av.getCharHeight() + av.getStartSeq();\r
337     oldSeq = seq;\r
338 \r
339     stretchGroup = av.getRubberbandGroup();\r
340 \r
341     if(stretchGroup == null)\r
342         stretchGroup = av.alignment.findGroup((Sequence)av.getAlignment().getSequenceAt(seq));\r
343 \r
344     else if(!stretchGroup.sequences.contains((Sequence)av.getAlignment().getSequenceAt(seq))\r
345             || stretchGroup.getStartRes()>res\r
346             || stretchGroup.getEndRes()<res)\r
347      {\r
348        stretchGroup = null;\r
349      }\r
350 \r
351     if(stretchGroup==null)\r
352     {\r
353       // define a new group here\r
354       SequenceGroup sg = new SequenceGroup();\r
355       sg.setStartRes(res);\r
356       sg.setEndRes(res);\r
357       sg.addSequence( (Sequence)av.getAlignment().getSequenceAt(seq) );\r
358       av.setRubberbandGroup( sg );\r
359       stretchGroup = sg;\r
360     }\r
361     else if( javax.swing.SwingUtilities.isRightMouseButton(evt))\r
362     {\r
363         jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu( parent , null);\r
364         pop.show(this, evt.getX(), evt.getY());\r
365 \r
366     // edit the properties of existing group\r
367     }\r
368 \r
369     if(stretchGroup!=null && stretchGroup.getEndRes()==res)\r
370       // Edit end res position of selected group\r
371       changeEndRes = true;\r
372 \r
373    else if(stretchGroup!=null && stretchGroup.getStartRes()==res)\r
374       // Edit end res position of selected group\r
375       changeStartRes = true;\r
376 \r
377 \r
378     seqCanvas.paintFlag = true;\r
379     repaint();\r
380 \r
381 \r
382   }\r
383 \r
384   boolean changeEndSeq = false;\r
385   boolean changeStartSeq = false;\r
386   boolean changeEndRes = false;\r
387   boolean changeStartRes = false;\r
388   SequenceGroup stretchGroup = null;\r
389 \r
390   public void doMouseReleasedDefineMode(MouseEvent evt)\r
391   {\r
392     changeEndRes = false;\r
393     changeStartRes = false;\r
394     stretchGroup = null;\r
395   }\r
396 \r
397 \r
398   boolean remove = false;\r
399   public void doMouseDraggedDefineMode(MouseEvent evt)\r
400   {\r
401     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
402     int y = evt.getY()/av.getCharHeight() + av.getStartSeq();\r
403 \r
404 \r
405     if(stretchGroup.getEndRes()==res)\r
406       // Edit end res position of selected group\r
407       changeEndRes = true;\r
408 \r
409     else if(stretchGroup.getStartRes()==res)\r
410       // Edit end res position of selected group\r
411       changeStartRes = true;\r
412 \r
413 \r
414     if(res<av.getStartRes())\r
415       res = av.getStartRes();\r
416     else if(res>av.getEndRes())\r
417       res = av.getEndRes();\r
418 \r
419     if(changeEndRes)\r
420     {\r
421       if(res>stretchGroup.getStartRes()-1)\r
422         stretchGroup.setEndRes( res );\r
423     }\r
424     else if(changeStartRes)\r
425     {\r
426       if(res<stretchGroup.getEndRes()+1)\r
427         stretchGroup.setStartRes( res );\r
428     }\r
429 \r
430 \r
431     int dragDirection = 0;\r
432     if (y > oldSeq)\r
433       dragDirection = 1;\r
434     else if (y < oldSeq)\r
435       dragDirection = -1;\r
436 \r
437     while (y != oldSeq)\r
438     {\r
439       // This routine ensures we don't skip any sequences, as the\r
440       // selection is quite slow.\r
441       Sequence seq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
442 \r
443       oldSeq += dragDirection;\r
444       Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq);\r
445 \r
446       if (stretchGroup.sequences.contains(nextSeq))\r
447       {\r
448         stretchGroup.deleteSequence(seq);\r
449         stretchGroup.deleteSequence(nextSeq);\r
450       }\r
451       else\r
452       {\r
453         stretchGroup.addSequence(seq);\r
454         stretchGroup.addSequence(nextSeq);\r
455       }\r
456     }\r
457     oldSeq = y;\r
458 \r
459     seqCanvas.paintFlag = true;\r
460     repaint();\r
461   }\r
462 \r
463 \r
464 }\r
465 \r
466 \r
467 \r
468 \r