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