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