Amend features/annotations in applet
[jalview.git] / src / jalview / appletgui / AnnotationLabels.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.event.*;\r
26 \r
27 import jalview.datamodel.*;\r
28 \r
29 public class AnnotationLabels\r
30     extends Panel implements ActionListener, MouseListener, MouseMotionListener\r
31 {\r
32   Image image;\r
33   boolean active = false;\r
34   AlignmentPanel ap;\r
35   AlignViewport av;\r
36   boolean resizing = false;\r
37   int oldY, mouseX;\r
38 \r
39   static String ADDNEW = "Add New Row";\r
40   static String EDITNAME = "Edit Label/Description";\r
41   static String HIDE = "Hide This Row";\r
42   static String SHOWALL = "Show All Hidden Rows";\r
43   static String OUTPUT_TEXT = "Show Values In Textbox";\r
44   static String COPYCONS_SEQ = "Copy Consensus Sequence";\r
45 \r
46   int scrollOffset = 0;\r
47   int selectedRow = -1;\r
48 \r
49   Tooltip tooltip;\r
50 \r
51   public AnnotationLabels(AlignmentPanel ap)\r
52   {\r
53     this.ap = ap;\r
54     this.av = ap.av;\r
55     setLayout(null);\r
56     addMouseListener(this);\r
57     addMouseMotionListener(this);\r
58   }\r
59 \r
60   public AnnotationLabels(AlignViewport av)\r
61   {\r
62     this.av = av;\r
63   }\r
64 \r
65   public void setScrollOffset(int y)\r
66   {\r
67     scrollOffset = y;\r
68     repaint();\r
69   }\r
70 \r
71   int getSelectedRow(int y)\r
72   {\r
73     int row = -1;\r
74     AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
75 \r
76     if (aa == null)\r
77     {\r
78       return row;\r
79     }\r
80 \r
81     int height = 0;\r
82     for (int i = 0; i < aa.length; i++)\r
83     {\r
84       if (!aa[i].visible)\r
85       {\r
86         continue;\r
87       }\r
88 \r
89       height += aa[i].height;\r
90       if (y < height)\r
91       {\r
92         row = i;\r
93         break;\r
94       }\r
95     }\r
96 \r
97     return row;\r
98   }\r
99 \r
100   public void actionPerformed(ActionEvent evt)\r
101   {\r
102     AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
103 \r
104     if (evt.getActionCommand().equals(ADDNEW))\r
105     {\r
106       AlignmentAnnotation newAnnotation = new AlignmentAnnotation("",\r
107           null,\r
108           new Annotation[ap.av.alignment.getWidth()]);\r
109 \r
110       if (!editLabelDescription(newAnnotation))\r
111       {\r
112         return;\r
113       }\r
114 \r
115       ap.av.alignment.addAnnotation(newAnnotation);\r
116       ap.av.alignment.setAnnotationIndex(newAnnotation, 0);\r
117     }\r
118     else if (evt.getActionCommand().equals(EDITNAME))\r
119     {\r
120       editLabelDescription(aa[selectedRow]);\r
121     }\r
122     else if (evt.getActionCommand().equals(HIDE))\r
123     {\r
124       aa[selectedRow].visible = false;\r
125     }\r
126     else if (evt.getActionCommand().equals(SHOWALL))\r
127     {\r
128       for (int i = 0; i < aa.length; i++)\r
129       {\r
130         aa[i].visible = true;\r
131       }\r
132     }\r
133     else if (evt.getActionCommand().equals(OUTPUT_TEXT))\r
134     {\r
135       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);\r
136       Frame frame = new Frame();\r
137       frame.add(cap);\r
138       jalview.bin.JalviewLite.addFrame(frame,\r
139                                        ap.alignFrame.getTitle() + " - " +\r
140                                        aa[selectedRow].label, 500, 100);\r
141       cap.setText(aa[selectedRow].toString());\r
142     }\r
143     else if (evt.getActionCommand().equals(COPYCONS_SEQ))\r
144     {\r
145       SequenceI cons = av.getConsensusSeq();\r
146       if (cons != null)\r
147       {\r
148         copy_annotseqtoclipboard(cons);\r
149       }\r
150 \r
151     }\r
152     ap.annotationPanel.adjustPanelHeight();\r
153     setSize(getSize().width, ap.annotationPanel.getSize().height);\r
154     ap.validate();\r
155     ap.paintAlignment(true);\r
156   }\r
157 \r
158   boolean editLabelDescription(AlignmentAnnotation annotation)\r
159   {\r
160     EditNameDialog dialog = new EditNameDialog(\r
161         annotation.label,\r
162         annotation.description,\r
163         "       Annotation Label",\r
164         "Annotation Description",\r
165         ap.alignFrame,\r
166         "Edit Annotation Name / Description",\r
167         500, 100);\r
168 \r
169     if (dialog.accept)\r
170     {\r
171       annotation.label = dialog.getName();\r
172       annotation.description = dialog.getDescription();\r
173       repaint();\r
174       return true;\r
175     }\r
176     else\r
177       return false;\r
178 \r
179   }\r
180 \r
181   public void mouseMoved(MouseEvent evt)\r
182   {\r
183     int row = getSelectedRow(evt.getY() - scrollOffset);\r
184 \r
185     if (row > -1)\r
186     {\r
187       if (tooltip == null)\r
188       {\r
189         tooltip = new Tooltip(ap.av.alignment.\r
190                               getAlignmentAnnotation()[row].\r
191                               description,\r
192                               this);\r
193       }\r
194       else\r
195       {\r
196         tooltip.setTip(ap.av.alignment.\r
197                        getAlignmentAnnotation()[row].description);\r
198       }\r
199     }\r
200     else if (tooltip != null)\r
201     {\r
202       tooltip.setTip("");\r
203     }\r
204 \r
205   }\r
206 \r
207   public void mouseDragged(MouseEvent evt)\r
208   {}\r
209 \r
210   public void mouseClicked(MouseEvent evt)\r
211   {}\r
212 \r
213   public void mouseReleased(MouseEvent evt)\r
214   {}\r
215 \r
216   public void mouseEntered(MouseEvent evt)\r
217   {}\r
218 \r
219   public void mouseExited(MouseEvent evt)\r
220   {}\r
221 \r
222   public void mousePressed(MouseEvent evt)\r
223   {\r
224     selectedRow = getSelectedRow(evt.getY() - scrollOffset);\r
225 \r
226     AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
227 \r
228     PopupMenu popup = new PopupMenu("Annotations");\r
229 \r
230     MenuItem item = new MenuItem(ADDNEW);\r
231     item.addActionListener(this);\r
232     popup.add(item);\r
233     item = new MenuItem(EDITNAME);\r
234     item.addActionListener(this);\r
235     popup.add(item);\r
236     item = new MenuItem(HIDE);\r
237     item.addActionListener(this);\r
238     popup.add(item);\r
239     item = new MenuItem(SHOWALL);\r
240     item.addActionListener(this);\r
241     popup.add(item);\r
242     this.add(popup);\r
243     item = new MenuItem(OUTPUT_TEXT);\r
244     item.addActionListener(this);\r
245     popup.add(item);\r
246 \r
247     if (aa[selectedRow] == ap.av.consensus)\r
248     {\r
249       popup.addSeparator();\r
250       final CheckboxMenuItem cbmi = new CheckboxMenuItem(\r
251           "Ignore Gaps In Consensus",\r
252           ap.av.getIgnoreGapsConsensus());\r
253 \r
254       cbmi.addItemListener(new ItemListener()\r
255       {\r
256         public void itemStateChanged(ItemEvent e)\r
257         {\r
258           ap.av.setIgnoreGapsConsensus(cbmi.getState());\r
259           ap.paintAlignment(true);\r
260         }\r
261       });\r
262       popup.add(cbmi);\r
263       item = new MenuItem(COPYCONS_SEQ);\r
264       item.addActionListener(this);\r
265       popup.add(item);\r
266     }\r
267 \r
268     popup.show(this, evt.getX(), evt.getY());\r
269 \r
270   }\r
271 \r
272   /**\r
273    * DOCUMENT ME!\r
274    *\r
275    * @param e DOCUMENT ME!\r
276    */\r
277   protected void copy_annotseqtoclipboard(SequenceI sq)\r
278   {\r
279     if (sq == null || sq.getLength() < 1)\r
280     {\r
281       return;\r
282     }\r
283     jalview.appletgui.AlignFrame.copiedSequences = new StringBuffer();\r
284     jalview.appletgui.AlignFrame.copiedSequences.append(sq.getName() + "\t" +\r
285         sq.getStart() + "\t" +\r
286         sq.getEnd() + "\t" +\r
287         sq.getSequenceAsString() + "\n");\r
288     if (av.hasHiddenColumns)\r
289     {\r
290       jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector();\r
291       for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)\r
292       {\r
293         int[] region = (int[])\r
294             av.getColumnSelection().getHiddenColumns().elementAt(i);\r
295 \r
296         jalview.appletgui.AlignFrame.copiedHiddenColumns.addElement(new int[]\r
297             {region[0],\r
298             region[1]});\r
299       }\r
300     }\r
301   }\r
302 \r
303   public void update(Graphics g)\r
304   {\r
305     paint(g);\r
306   }\r
307 \r
308   public void paint(Graphics g)\r
309   {\r
310     int w = getSize().width;\r
311     if (image == null || w != image.getWidth(this))\r
312     {\r
313       image = createImage(w, ap.annotationPanel.getSize().height);\r
314     }\r
315 \r
316     drawComponent(image.getGraphics(), w);\r
317     g.drawImage(image, 0, 0, this);\r
318   }\r
319 \r
320   public void drawComponent(Graphics g, int width)\r
321   {\r
322     g.setFont(av.getFont());\r
323     FontMetrics fm = g.getFontMetrics(av.getFont());\r
324     g.setColor(Color.white);\r
325     g.fillRect(0, 0, getSize().width, getSize().height);\r
326 \r
327     g.translate(0, scrollOffset);\r
328     g.setColor(Color.black);\r
329 \r
330     AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
331     int y = g.getFont().getSize();\r
332     int x = 0;\r
333 \r
334     if (aa != null)\r
335     {\r
336       for (int i = 0; i < aa.length; i++)\r
337       {\r
338         if (!aa[i].visible)\r
339         {\r
340           continue;\r
341         }\r
342 \r
343         x = width - fm.stringWidth(aa[i].label) - 3;\r
344 \r
345         if (aa[i].graph > 0)\r
346         {\r
347           y += (aa[i].height / 3);\r
348         }\r
349 \r
350         g.drawString(aa[i].label, x, y);\r
351 \r
352         if (aa[i].graph > 0)\r
353         {\r
354           y += (2 * aa[i].height / 3);\r
355         }\r
356         else\r
357         {\r
358           y += aa[i].height;\r
359         }\r
360       }\r
361     }\r
362   }\r
363 \r
364 }\r