add control a key to select all
[jalview.git] / src / jalview / gui / AlignmentPanel.java
1 package jalview.gui;\r
2 \r
3 import jalview.jbgui.GAlignmentPanel;\r
4 import jalview.schemes.*;\r
5 import jalview.analysis.*;\r
6 import jalview.datamodel.*;\r
7 import java.awt.*;\r
8 import java.awt.event.*;\r
9 import java.awt.print.*;\r
10 \r
11 public class AlignmentPanel extends GAlignmentPanel implements AdjustmentListener, Printable\r
12 {\r
13 \r
14   AlignViewport     av;\r
15   OverviewPanel overviewPanel;\r
16   SeqPanel   seqPanel;\r
17   IdPanel    idPanel;\r
18   SecondaryStructurePanel ssPanel;\r
19   public AlignFrame alignFrame;\r
20   ScalePanel scalePanel;\r
21   ScorePanel scorePanel;\r
22 \r
23   public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
24   {\r
25     alignFrame = af;\r
26     this.av         = av;\r
27     seqPanel        = new SeqPanel  (av, this);\r
28     idPanel         = new IdPanel   (av, this);\r
29     scalePanel = new ScalePanel(av, this);\r
30     scorePanel = new ScorePanel(av);\r
31     ssPanel = new SecondaryStructurePanel(av);\r
32 \r
33     secondaryPanelHolder.add(ssPanel, BorderLayout.CENTER);\r
34     idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
35     idPanel.addNotify();\r
36     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
37     scorePanelHolder.add(scorePanel, BorderLayout.CENTER);\r
38     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
39     setScrollValues(0,0);\r
40 \r
41     hscroll.addAdjustmentListener(this);\r
42     vscroll.addAdjustmentListener(this);\r
43 \r
44     addComponentListener(new ComponentAdapter()\r
45    {\r
46      public void componentResized(ComponentEvent evt)\r
47      {\r
48           RefreshPanels();\r
49      }\r
50    });\r
51 \r
52 \r
53    hscroll.setFocusable(false);\r
54    vscroll.setFocusable(false);\r
55    setFocusable(true);\r
56 \r
57    addKeyListener(new KeyAdapter()\r
58    {\r
59      public void keyPressed(KeyEvent evt)\r
60      {\r
61        switch(evt.getKeyCode())\r
62        {\r
63          case 27: // escape key\r
64            av.setRubberbandGroup(null);\r
65            RefreshPanels();\r
66            break;\r
67          case KeyEvent.VK_X:\r
68            alignFrame.cut_actionPerformed(null);\r
69            break;\r
70          case KeyEvent.VK_C:\r
71            alignFrame.copy_actionPerformed(null);\r
72            break;\r
73          case KeyEvent.VK_V:\r
74            alignFrame.paste(true);\r
75            break;\r
76          case KeyEvent.VK_A:\r
77            alignFrame.selectAllSequenceMenuItem_actionPerformed(null);\r
78            break;\r
79 \r
80        }\r
81 \r
82       /* public void doKeyPressed(KeyEvent evt)\r
83        {\r
84 \r
85          if (evt.isControlDown() && evt.getKeyChar() == 'f')\r
86            findMenuItem_actionPerformed(null);\r
87        }*/\r
88 \r
89      }\r
90    });\r
91 \r
92 \r
93   }\r
94 \r
95  public void highlightSearchResults(int [] results)\r
96  {\r
97    seqPanel.seqCanvas.highlightSearchResults( results );\r
98 \r
99    // do we need to scroll the panel?\r
100    if(results!=null && (av.getStartSeq()>results[0]\r
101                         || av.getEndSeq()<results[0]\r
102                         || av.getStartRes()>results[1]\r
103                         || av.getEndRes()<results[2]))\r
104        setScrollValues(results[1], results[0]);\r
105 \r
106 \r
107  }\r
108 \r
109 \r
110  public OverviewPanel getOverviewPanel()\r
111  {\r
112    return overviewPanel;\r
113  }\r
114 \r
115  public void setOverviewPanel(OverviewPanel op)\r
116  {\r
117    overviewPanel = op;\r
118  }\r
119 \r
120 \r
121   public void setGraphPanelVisible(boolean b)\r
122   {\r
123     idSpaceFillerPanel.setVisible(b);\r
124     scorePanelHolder.setVisible(b);\r
125 \r
126     RefreshPanels();\r
127     // bit annoying to call this twice, can you do better?\r
128     RefreshPanels();\r
129   }\r
130 \r
131   public void setSecondaryStructureVisible(boolean b)\r
132   {\r
133     secondaryPanelHolder.setVisible(b);\r
134     RefreshPanels();\r
135   }\r
136 \r
137   public void setWrapAlignment(boolean wrap)\r
138   {\r
139     scorePanelHolder.setVisible(!wrap);\r
140     scalePanelHolder.setVisible(!wrap);\r
141     secondaryPanelHolder.setVisible(!wrap);\r
142 \r
143     hscroll.setVisible(!wrap);\r
144 \r
145     idSpaceFillerPanel.setVisible(!wrap);\r
146     idSpaceFillerPanel1.setVisible(!wrap);\r
147 \r
148     RefreshPanels();\r
149 \r
150   }\r
151 \r
152 \r
153   public void setColourScheme()\r
154   {\r
155     ColourSchemeI cs = av.getGlobalColourScheme();\r
156 \r
157     if(av.getConservationSelected())\r
158     {\r
159 \r
160        Alignment al = (Alignment)av.getAlignment();\r
161        Conservation c = new Conservation("All",\r
162                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
163                             al.getWidth() );\r
164 \r
165        c.calculate();\r
166        c.verdict(false, 100);\r
167        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
168 \r
169        av.setGlobalColourScheme( ccs );\r
170 \r
171     }\r
172 \r
173     RefreshPanels();\r
174   }\r
175 \r
176   public void RefreshPanels()\r
177   {\r
178     requestFocus();\r
179     invalidate();\r
180     seqPanel.seqCanvas.paintFlag = true;\r
181     idPanel.idCanvas.paintFlag = true;\r
182     idPanelHolder.setPreferredSize( idPanel.idCanvas.getPreferredSize() );\r
183 \r
184     if(av.getWrapAlignment())\r
185     {\r
186       int max = av.alignment.getWidth()/ (seqPanel.seqCanvas.getWidth()/av.charWidth)+1;\r
187 \r
188       int h  = (av.alignment.getHeight() + 2)*av.charHeight;\r
189       vextent = seqPanel.seqCanvas.getHeight()/h;\r
190       vscroll.setValues(0,vextent,0,max);\r
191     }\r
192     else\r
193 \r
194     setScrollValues(av.getStartRes(), av.getStartSeq());\r
195     av.getConsensus(true);\r
196     if(overviewPanel!=null)\r
197       overviewPanel.updateOverviewImage();\r
198 \r
199     validate();\r
200     repaint();\r
201 \r
202   }\r
203 \r
204   int hextent = 0;\r
205   int vextent = 0;\r
206 \r
207   public void setScrollValues(int x, int y)\r
208   {\r
209     hextent = seqPanel.seqCanvas.getWidth()/av.getCharWidth();\r
210     vextent = seqPanel.seqCanvas.getHeight()/av.getCharHeight();\r
211 \r
212     if(hextent+x  >  av.getAlignment().getWidth())\r
213       x =  av.getAlignment().getWidth()- hextent;\r
214 \r
215     if(vextent+y > av.getAlignment().getHeight())\r
216       y = av.getAlignment().getHeight() - vextent;\r
217 \r
218     if(y<0)\r
219       y = 0;\r
220 \r
221     if(x<0)\r
222       x=0;\r
223 \r
224     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
225     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
226 \r
227 \r
228     repaint();\r
229 \r
230   }\r
231 \r
232 \r
233   public void adjustmentValueChanged(AdjustmentEvent evt)\r
234   {\r
235 \r
236     if (evt.getSource() == hscroll)\r
237     {\r
238       int x = hscroll.getValue();\r
239       av.setStartRes(x);\r
240       av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
241     }\r
242 \r
243     if (evt.getSource() == vscroll)\r
244     {\r
245       int offy = vscroll.getValue();\r
246       if (av.getWrapAlignment())\r
247       {\r
248         av.setStartRes( vscroll.getValue() * av.getChunkWidth());\r
249         // System.out.println(vscroll.getValue()+" "+ av.getChunkWidth());\r
250       //  int resSpan = av.alignment.getWidth()/ (seqPanel.seqCanvas.getWidth()/av.charWidth)+1;\r
251      //   int h  = (av.alignment.getHeight() + 2)*av.charHeight;\r
252       //  vextent = seqPanel.seqCanvas.getHeight()/h;\r
253      //   vscroll.setValues(0,vextent,0,max);\r
254 \r
255 \r
256       // av.setStartSeq(  );\r
257       }\r
258       else\r
259       {\r
260         av.setStartSeq(offy);\r
261         av.setEndSeq(offy + seqPanel.seqCanvas.getHeight() / av.getCharHeight());\r
262       }\r
263     }\r
264 \r
265 \r
266     if(overviewPanel!=null)\r
267       overviewPanel.setBoxPosition();\r
268 \r
269     seqPanel.seqCanvas.paintFlag=true;\r
270     repaint();\r
271   }\r
272 \r
273 \r
274 \r
275   public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
276   {\r
277     if(av.getWrapAlignment())\r
278     {\r
279      return PrintWrappedAlignment(pg, pf, pi);\r
280     }\r
281 \r
282     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
283 \r
284     int pwidth = (int)pf.getImageableWidth();\r
285     int pheight = (int)pf.getImageableHeight();\r
286     int idWidth = (int)idPanel.idCanvas.getLabelWidth().getWidth();\r
287 \r
288 \r
289     pg.setColor(Color.white);\r
290     pg.fillRect(0,0,pwidth, pheight);\r
291     pg.setFont( av.getFont() );\r
292 \r
293     ////////////////////////////////////\r
294     /// How many sequences and residues can we fit on a printable page?\r
295     int totalRes = (pwidth - idWidth)/av.getCharWidth();\r
296     int totalSeq = (int)((pheight - 30)/av.getCharHeight())-1;\r
297     int pagesWide = av.getAlignment().getWidth() / totalRes +1;\r
298     int pagesHigh = av.getAlignment().getHeight() / totalSeq +1;\r
299 \r
300     if (pi >= pagesWide*pagesHigh)\r
301      return Printable.NO_SUCH_PAGE;\r
302 \r
303     /////////////////////////////\r
304     /// Only print these sequences and residues on this page\r
305     int startRes, endRes, startSeq, endSeq;\r
306     startRes = (pi % pagesWide) * totalRes;\r
307     endRes = startRes + totalRes-1;\r
308     if(endRes>av.getAlignment().getWidth())\r
309       endRes = av.getAlignment().getWidth();\r
310 \r
311      startSeq = (pi / pagesWide) * totalSeq;\r
312      endSeq = startSeq + totalSeq;\r
313      if(endSeq > av.getAlignment().getHeight())\r
314        endSeq = av.getAlignment().getHeight();\r
315 \r
316 \r
317     ////////////////\r
318     //draw Scale\r
319     pg.translate(idWidth,0);\r
320     scalePanel.scaleCanvas.drawScale(pg, startRes, endRes, pwidth-idWidth);\r
321 \r
322     pg.translate(-idWidth, 30);\r
323     ////////////////\r
324     // Draw the ids\r
325     Color currentColor=null;\r
326     Color currentTextColor=null;\r
327     for(int i=startSeq; i<endSeq; i++)\r
328     {\r
329       if (av.getSelection().contains(av.getAlignment().getSequenceAt(i)))\r
330       {\r
331         currentColor = Color.gray;\r
332         currentTextColor = Color.black;\r
333       }\r
334       else\r
335       {\r
336         currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
337         currentTextColor = Color.black;\r
338       }\r
339 \r
340       pg.setColor(currentColor);\r
341       pg.fillRect(0,  jalview.analysis.AlignmentUtil.getPixelHeight(startSeq, i, av.getCharHeight()),\r
342                               idWidth,\r
343                               av.getCharHeight());\r
344 \r
345       pg.setColor(currentTextColor);\r
346 \r
347       String string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
348       pg.drawString(string, 0,  jalview.analysis.AlignmentUtil.getPixelHeight\r
349                     (startSeq, i, av.getCharHeight()) + av.getCharHeight() - (av.getCharHeight() / 5));\r
350     }\r
351 \r
352     // draw main sequence panel\r
353     pg.translate(idWidth,0);\r
354     pg.setClip(0,0,pwidth-idWidth, pheight);\r
355     seqPanel.seqCanvas.drawPanel(pg,startRes,endRes,startSeq,endSeq,startRes,startSeq,0);\r
356 \r
357     return Printable.PAGE_EXISTS;\r
358   }\r
359 \r
360   class VPanel extends javax.swing.JPanel\r
361   {\r
362     Image image;\r
363     public VPanel(Image i)\r
364     {\r
365       image = i;\r
366       repaint();\r
367     }\r
368     public void paintComponent(Graphics g)\r
369     {\r
370       if(image!=null)\r
371         g.drawImage(image,0,0,this);\r
372     }\r
373 \r
374   }\r
375 \r
376   public int PrintWrappedAlignment(Graphics pg, PageFormat pf, int pi)\r
377   {\r
378     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
379 \r
380     int pwidth = (int)pf.getImageableWidth();\r
381     int pheight = (int)pf.getImageableHeight();\r
382     int idWidth = (int)idPanel.idCanvas.getLabelWidth().getWidth();\r
383 \r
384     if( seqPanel.seqCanvas.getWidth() < pwidth-idWidth)\r
385       pwidth = seqPanel.seqCanvas.getWidth() + idWidth;\r
386 \r
387     pg.setColor(Color.white);\r
388     pg.fillRect(0,0,pwidth, pheight);\r
389     pg.setFont( av.getFont() );\r
390 \r
391     ////////////////////////////////////\r
392     /// How many sequences and residues can we fit on a printable page?\r
393     AlignmentI da = av.alignment;\r
394     int endy   = da.getHeight();\r
395     int chunkHeight =  (da.getHeight() + 2)*av.charHeight;\r
396     int chunkWidth  =   (pwidth-idWidth)/av.charWidth;\r
397 \r
398     int noChunksOnPage = pheight / chunkHeight;\r
399     int totalChunks = endy / chunkHeight;\r
400 \r
401     if ( pi*noChunksOnPage > totalChunks )\r
402      return Printable.NO_SUCH_PAGE;\r
403 \r
404     ////////////////\r
405     // Draw the ids\r
406     pg.setClip(0,0,pwidth, noChunksOnPage*chunkHeight);\r
407 \r
408     int row = pi*noChunksOnPage;\r
409     pg.setColor(Color.black);\r
410     for(int ypos=2*av.charHeight;\r
411         ypos <= pheight && row*chunkWidth<da.getWidth();\r
412         ypos += chunkHeight, row++ )\r
413     {\r
414       for (int i = 0; i < endy; i++)\r
415       {\r
416         SequenceI s = da.getSequenceAt(i);\r
417         pg.drawString(s.getDisplayId(), 0,\r
418                       AlignmentUtil.getPixelHeight(0, i, av.charHeight) + ypos +\r
419                       av.charHeight - (av.charHeight / 5));\r
420       }\r
421     }\r
422 \r
423     // draw main sequence panel\r
424     pg.translate(idWidth,0);\r
425     seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth-idWidth, pheight, pi*noChunksOnPage*chunkWidth);\r
426 \r
427 \r
428     return Printable.NO_SUCH_PAGE;//.PAGE_EXISTS;\r
429 \r
430   }\r
431 }\r
432 \r
433 \r
434 \r