Preparing for groupselect mode
[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       public void mouseDragged(MouseEvent evt)\r
44       {\r
45         if(av.groupDefiningMode)\r
46           doMouseDraggedDefineMode(evt);\r
47         else\r
48           doMouseDragged(evt);\r
49       }\r
50     });\r
51 \r
52     addMouseListener( new MouseAdapter()\r
53     {\r
54       public void mouseReleased(MouseEvent evt)\r
55       {\r
56         if(av.groupDefiningMode)\r
57           doMouseReleasedDefineMode(evt);\r
58         else\r
59           doMouseReleased(evt);\r
60       }\r
61       public void mousePressed(MouseEvent evt)\r
62       {\r
63         if(av.groupDefiningMode)\r
64           doMousePressedDefineMode(evt);\r
65         else\r
66           doMousePressed(evt);\r
67       }\r
68 \r
69     });\r
70     repaint();\r
71   }\r
72 \r
73 \r
74   public void doMouseReleased(MouseEvent evt) {\r
75 \r
76     int x = evt.getX();\r
77     int res = x/av.getCharWidth() + av.getStartRes();\r
78 \r
79     endres = res;\r
80 \r
81       // This is to detect edits - we're at the end of an edit if mouse is up\r
82     editFlag = false;\r
83     startseq = -1;\r
84     startres = -1;\r
85     lastres  = -1;\r
86     if(seqEditOccurred>-1)\r
87       updateConservation(seqEditOccurred);\r
88 \r
89     seqEditOccurred = -1;\r
90 \r
91     parent.RefreshPanels();\r
92     repaint();\r
93 \r
94   }\r
95 \r
96   public void doMousePressed(MouseEvent evt) {\r
97     parent.alignFrame.addHistoryItem("sequence edit");\r
98     int seq;\r
99     int res;\r
100 \r
101     int x = evt.getX();\r
102     int y = evt.getY();\r
103 \r
104     res = x/av.getCharWidth() + av.getStartRes();\r
105     seq = y/av.getCharHeight() + av.getStartSeq();\r
106 \r
107     if (seq < av.getAlignment().getHeight() && res < av.getAlignment().getSequenceAt(seq).getLength())\r
108     {\r
109       //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);\r
110       // Find the residue's position in the sequence (res is the position\r
111       // in the alignment\r
112 \r
113       startseq = seq;\r
114 \r
115       if (startseq == (av.getAlignment().getHeight()-1)) {\r
116         padseq = 1;\r
117       } else {\r
118         padseq = 1;\r
119       }\r
120 \r
121       startres = res;\r
122       lastres = res;\r
123 \r
124       } else {\r
125       startseq = -1;\r
126       startres = -1;\r
127       lastres = -1;\r
128     }\r
129 \r
130     return;\r
131   }\r
132 \r
133   public void doMouseMoved(MouseEvent evt)\r
134   {\r
135     int res=0, seq=0;\r
136     int x = evt.getX();\r
137     int y = evt.getY();\r
138     if(av.wrapAlignment)\r
139     {\r
140       y -= 2*av.charHeight;\r
141       int chunkHeight = (av.getAlignment().getHeight()+2)*av.charHeight;\r
142 \r
143 \r
144       res =   (int)((y/chunkHeight)*(getWidth()/av.charWidth)) +  x/av.getCharWidth() + av.getStartRes();\r
145 \r
146       System.out.println( ((y/chunkHeight)*(getWidth()/av.charWidth)) +" "+((x / av.getCharWidth()) + av.getStartRes()) );\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     editFlag = true;\r
179     int x = evt.getX();\r
180 \r
181     int res = x/av.getCharWidth() + av.getStartRes();\r
182     if (res < 0) {res = 0;}\r
183 \r
184     if (res  != lastres) {\r
185       if (startseq != -1) {\r
186 \r
187         // Group editing\r
188         if (av.getGroupEdit()) {\r
189           SequenceGroup sg = av.getAlignment().findGroup(startseq);\r
190 \r
191           if(sg!=null)\r
192           if (res < av.getAlignment().getWidth() && res < lastres)\r
193           {\r
194             boolean flag = false;\r
195             for (int i= 0 ; i < sg.getSize(); i++)\r
196             {\r
197               SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
198               for (int j=lastres-1; j >= res; j--)\r
199               {\r
200                 if (!flag)\r
201                 {\r
202                   if (s.getSequence().charAt(j)!=av.getAlignment().getGapCharacter() &&\r
203                       s.getSequence().charAt(j)==' ')\r
204                   {\r
205                     res = j+1;\r
206                     flag = true;\r
207                   }\r
208                 }\r
209               }\r
210             }\r
211           }\r
212 \r
213           if(sg!=null)\r
214           for (int i= 0 ; i < sg.getSize(); i++)\r
215           {\r
216             SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
217             boolean found = false;\r
218             int sno = -1;\r
219             for (int k = 0; k < av.getAlignment().getHeight(); k++)\r
220             {\r
221               if (av.getAlignment().getSequenceAt(k) == s)\r
222               {\r
223                 found = true;\r
224                 sno = k;\r
225                 break;\r
226               }\r
227             }\r
228             if (found && sno != -1) {\r
229               if (res < av.getAlignment().getWidth() && res > lastres)\r
230               {\r
231                 for (int j = lastres; j < res; j++)\r
232                   insertChar(j,sno);\r
233 \r
234                 int index = av.getAlignment().findIndex(s);\r
235                 if (index != -1)\r
236                   drawChars(index,index+1,lastres);\r
237 \r
238 \r
239               } else if (res < av.getAlignment().getWidth() && res < lastres)\r
240               {\r
241                 for (int j = res; j < lastres; j++)\r
242                 {\r
243                   deleteChar(j,res,sno);\r
244                   startres = res;\r
245                 }\r
246                 int index = av.getAlignment().findIndex(s);\r
247                 if (index != -1)\r
248                   drawChars(index,index+1,res);\r
249 \r
250               }\r
251             }\r
252 \r
253           }\r
254           lastres = res;\r
255         } else {\r
256 \r
257 \r
258           if (res < av.getAlignment().getWidth() && res > lastres) {\r
259             // dragging to the right\r
260             for (int j = lastres; j < res; j++)\r
261               insertChar(j,startseq);\r
262 \r
263             drawChars(startseq,startseq+1,lastres);\r
264 \r
265           } else if (res < av.getAlignment().getWidth() && res < lastres)\r
266           {\r
267 \r
268             // dragging to the left\r
269             for (int j = res; j < lastres; j++) {\r
270               deleteChar(j,res,startseq);\r
271               startres = res;\r
272             }\r
273             drawChars(startseq,startseq+1,res);\r
274           }\r
275         }\r
276       }\r
277       lastres = res;\r
278     }\r
279 \r
280     repaint();\r
281     return;\r
282   }\r
283 \r
284   public void drawChars(int seqstart, int seqend, int start) {\r
285     seqCanvas.drawPanel(seqCanvas.gg, start,av.getEndRes(),seqstart,seqend,av.getStartRes(),av.getStartSeq(),0);\r
286     repaint();\r
287   }\r
288 \r
289   public void insertChar(int j, int seq)\r
290   {\r
291     av.getAlignment().getSequenceAt(seq).insertCharAt(j, av.getGapCharacter());\r
292     seqEditOccurred=seq;\r
293   }\r
294 \r
295   public void deleteChar(int j, int res, int seq)\r
296   {\r
297 \r
298     if (av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='.' ||\r
299         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='-' ||\r
300         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)==' ' )\r
301     {\r
302         av.getAlignment().getSequenceAt(seq).deleteCharAt(j);\r
303     }\r
304 \r
305     av.getAlignment().getWidth();\r
306     repaint();\r
307     seqEditOccurred=seq;\r
308   }\r
309 \r
310 \r
311   void updateConservation(int i)\r
312   {\r
313     Alignment al = (Alignment) av.getAlignment();\r
314     SequenceGroup sg = av.alignment.findGroup( al.getSequenceAt(i));\r
315     if(sg==null || !(sg.cs instanceof ConservationColourScheme))\r
316       return;\r
317 \r
318     Conservation c = sg.getConservation();\r
319 \r
320     c = new Conservation("All", al.cons,\r
321                          ResidueProperties.propHash, 3, sg.sequences, 0,\r
322                          al.getWidth());\r
323     c.calculate();\r
324     c.verdict(false, 100);\r
325     sg.setConservation(c);\r
326     ConservationColourScheme ccs = (ConservationColourScheme)sg.cs;\r
327     ccs.conserve = c;\r
328   }\r
329 \r
330 \r
331   public void setColourScheme(ColourSchemeI cs, boolean showConservation)\r
332   {\r
333     seqCanvas.paintFlag = true;\r
334     if (av.getSelection().size() == 0)\r
335     {\r
336       seqCanvas.globalColorScheme = cs;\r
337       for (int i = 0; i < av.alignment.getGroups().size();i++)\r
338       {\r
339         SequenceGroup sg = (SequenceGroup)av.alignment.getGroups().elementAt(i);\r
340         sg.cs = cs;\r
341         if(!showConservation\r
342             && !(sg.cs instanceof Blosum62ColourScheme)\r
343             && sg.cs instanceof ConservationColourScheme)\r
344          {\r
345            // remove ConservationColouring from existing Conservation group\r
346            ConservationColourScheme ccs = (ConservationColourScheme)sg.cs;\r
347            sg.cs = ccs.cs;\r
348          }\r
349          else if(showConservation && !(sg.cs instanceof ConservationColourScheme))\r
350          {\r
351            // add ConservationColouring to new group\r
352            Conservation c = sg.getConservation();\r
353            Alignment al = (Alignment) av.getAlignment();\r
354            c = new Conservation("All", al.cons,\r
355                                 ResidueProperties.propHash, 3, sg.sequences, 0,\r
356                                 al.getWidth() );\r
357            c.calculate();\r
358            c.verdict(false, 100);\r
359            sg.setConservation(c);\r
360            sg.cs = new ConservationColourScheme(sg);\r
361          }\r
362       }\r
363     }\r
364     else\r
365     {\r
366       SequenceGroup sg = av.alignment.findGroup((Sequence)av.sel.sequenceAt(0));\r
367 \r
368       if( isNewSelection(sg) )\r
369       {\r
370         sg = av.getAlignment().addGroup();\r
371         for (int i=0; i < av.getSelection().size(); i++)\r
372         {\r
373           av.alignment.removeFromGroup(av.alignment.findGroup( (Sequence) av.\r
374               sel.sequenceAt(i)),\r
375                                        (Sequence) av.sel.sequenceAt(i));\r
376           av.alignment.addToGroup(sg, (Sequence) av.sel.sequenceAt(i));\r
377         }\r
378       }\r
379 \r
380 \r
381       sg.cs = cs;\r
382 \r
383       // Selection is made, we only want to change the conservationColour for selected group\r
384       if(  showConservation\r
385            && !(sg.cs instanceof ConservationColourScheme)\r
386            && !(sg.cs instanceof Blosum62ColourScheme))\r
387       {\r
388         Conservation c = sg.getConservation();\r
389         Alignment al = (Alignment) av.getAlignment();\r
390 \r
391         c = new Conservation("All", al.cons,\r
392                              ResidueProperties.propHash, 3, sg.sequences, 0,\r
393                              al.getWidth() );\r
394         c.calculate();\r
395         c.verdict(false, 100);\r
396         sg.setConservation(c);\r
397         sg.cs = new ConservationColourScheme(sg);\r
398     }\r
399     else  if( !showConservation && sg.cs instanceof ConservationColourScheme)\r
400     {\r
401       ConservationColourScheme ccs = (ConservationColourScheme)sg.cs;\r
402       sg.cs = ccs.cs;\r
403     }\r
404    }\r
405    repaint();\r
406   }\r
407 \r
408   boolean isNewSelection(SequenceGroup sg)\r
409   {\r
410     if(sg==null)\r
411       return true;\r
412 \r
413     if(sg.getSize()!=av.getSelection().size())\r
414       return true;\r
415 \r
416     for(int i=0; i<sg.getSize(); i++)\r
417      if( !av.getSelection().contains( sg.getSequenceAt(i) ))\r
418        return true;\r
419 \r
420     return false;\r
421   }\r
422 \r
423 \r
424   public ColourSchemeI getColourScheme()\r
425   {\r
426     if(av.getSelection().size()>0)\r
427        return av.alignment.findGroup((Sequence)av.sel.sequenceAt(0)).cs;\r
428     else\r
429       return seqCanvas.globalColorScheme;\r
430   }\r
431 \r
432   public void doMousePressedDefineMode(MouseEvent evt)\r
433   {\r
434     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
435     int seq = evt.getY()/av.getCharHeight() + av.getStartSeq();\r
436 \r
437     stretchGroup = av.alignment.findGroup((Sequence)av.getAlignment().getSequenceAt(seq));\r
438 \r
439     if(stretchGroup!=null  && stretchGroup.getEndRes()==res)\r
440     {\r
441       // Edit end res position of selected group\r
442       changeEndRes = true;\r
443     }\r
444     else if(stretchGroup!=null  && stretchGroup.getStartRes()==res)\r
445     {\r
446       // Edit end res position of selected group\r
447       changeStartRes = true;\r
448     }\r
449 \r
450 \r
451   }\r
452 \r
453   boolean changeEndRes = false;\r
454   boolean changeStartRes = false;\r
455   SequenceGroup stretchGroup = null;\r
456 \r
457   public void doMouseReleasedDefineMode(MouseEvent evt)\r
458   {\r
459     changeEndRes = false;\r
460     changeStartRes = false;\r
461   }\r
462 \r
463   public void doMouseDraggedDefineMode(MouseEvent evt)\r
464   {\r
465     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
466     int seq = evt.getY()/av.getCharHeight() + av.getStartSeq();\r
467 \r
468     if(res<av.getStartRes())\r
469       res = av.getStartRes();\r
470     else if(res>av.getEndRes())\r
471       res = av.getEndRes();\r
472 \r
473     if(changeEndRes)\r
474     {\r
475       if(res>stretchGroup.getStartRes()-1)\r
476         stretchGroup.setEndRes( res );\r
477     }\r
478     else if(changeStartRes)\r
479     {\r
480       if(res<stretchGroup.getEndRes()+1)\r
481         stretchGroup.setStartRes( res );\r
482     }\r
483     seqCanvas.paintFlag = true;\r
484     repaint();\r
485 \r
486   }\r
487 \r
488 }\r
489 \r
490 \r
491 \r
492 \r