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