5eee4bc673fad906af2e3d0b269cd97cb4899830
[jalviewjs.git] / unused / appletgui / FeatureRenderer.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)\r
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors\r
4  * \r
5  * This file is part of Jalview.\r
6  * \r
7  * Jalview is free software: you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License \r
9  * as published by the Free Software Foundation, either version 3\r
10  * of the License, or (at your option) any later version.\r
11  *  \r
12  * Jalview is distributed in the hope that it will be useful, but \r
13  * WITHOUT ANY WARRANTY; without even the implied warranty \r
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
15  * PURPOSE.  See the GNU General Public License for more details.\r
16  * \r
17  * You should have received a copy of the GNU General Public License\r
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
19  * The Jalview Authors are detailed in the 'AUTHORS' file.\r
20  */\r
21 package jalview.appletgui;\r
22 \r
23 import jalview.datamodel.SearchResults;\r
24 import jalview.datamodel.SequenceFeature;\r
25 import jalview.datamodel.SequenceI;\r
26 import jalview.io.FeaturesFile;\r
27 import jalview.schemes.AnnotationColourGradient;\r
28 import jalview.schemes.GraduatedColor;\r
29 import jalview.schemes.UserColourScheme;\r
30 import jalview.util.MessageManager;\r
31 import jalview.viewmodel.AlignmentViewport;\r
32 \r
33 import java.awt.BorderLayout;\r
34 import javax.swing.JButton;\r
35 import java.awt.Color;\r
36 import java.awt.Dimension;\r
37 import java.awt.Font;\r
38 import java.awt.Graphics;\r
39 import java.awt.GridLayout;\r
40 import javax.swing.JLabel;\r
41 import javax.swing.JPanel;\r
42 import javax.swing.JScrollPane;\r
43 import javax.swing.JTextArea;\r
44 import javax.swing.JTextField;\r
45 import java.awt.event.ActionEvent;\r
46 import java.awt.event.ActionListener;\r
47 import java.util.Hashtable;\r
48 \r
49 /**\r
50  * DOCUMENT ME!\r
51  * \r
52  * @author $author$\r
53  * @version $Revision$\r
54  */\r
55 public class FeatureRenderer extends\r
56         jalview.renderer.seqfeatures.FeatureRenderer\r
57 {\r
58 \r
59   // Holds web links for feature groups and feature types\r
60   // in the form label|link\r
61   Hashtable featureLinks = null;\r
62 \r
63   /**\r
64    * Creates a new FeatureRenderer object.\r
65    * \r
66    * @param av\r
67    *          DOCUMENT ME!\r
68    */\r
69   public FeatureRenderer(AlignmentViewport av)\r
70   {\r
71     super();\r
72     this.av = av;\r
73 \r
74     setTransparencyAvailable(!System.getProperty("java.version")\r
75             .startsWith("1.1"));\r
76   }\r
77 \r
78   static String lastFeatureAdded;\r
79 \r
80   static String lastFeatureGroupAdded;\r
81 \r
82   static String lastDescriptionAdded;\r
83 \r
84   int featureIndex = 0;\r
85 \r
86   boolean deleteFeature = false;\r
87 \r
88   FeatureColourPanel colourPanel;\r
89 \r
90   class FeatureColourPanel extends JPanel\r
91   {\r
92     String label = "";\r
93 \r
94     private Color maxCol;\r
95 \r
96     private boolean isColourByLabel, isGcol;\r
97 \r
98     /**\r
99      * render a feature style in the amend feature dialog box\r
100      */\r
101     public void updateColor(Object newcol)\r
102     {\r
103 \r
104       Color bg, col = null;\r
105       GraduatedColor gcol = null;\r
106       String vlabel = "";\r
107       if (newcol instanceof Color)\r
108       {\r
109         isGcol = false;\r
110         col = (Color) newcol;\r
111         gcol = null;\r
112       }\r
113       else if (newcol instanceof GraduatedColor)\r
114       {\r
115         isGcol = true;\r
116         gcol = (GraduatedColor) newcol;\r
117         col = null;\r
118       }\r
119       else\r
120       {\r
121         throw new Error(\r
122                 MessageManager\r
123                         .getString("error.invalid_colour_for_mycheckbox"));\r
124       }\r
125       if (col != null)\r
126       {\r
127         setBackground(bg = col);\r
128       }\r
129       else\r
130       {\r
131         if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)\r
132         {\r
133           vlabel += " "\r
134                   + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"\r
135                           : "(<)");\r
136         }\r
137         if (isColourByLabel = gcol.isColourByLabel())\r
138         {\r
139           setBackground(bg = Color.white);\r
140           vlabel += " (by Label)";\r
141         }\r
142         else\r
143         {\r
144           setBackground(bg = gcol.getMinColor());\r
145           maxCol = gcol.getMaxColor();\r
146         }\r
147       }\r
148       label = vlabel;\r
149       setBackground(bg);\r
150       repaint();\r
151     }\r
152 \r
153     FeatureColourPanel()\r
154     {\r
155       super(null);\r
156     }\r
157 \r
158     public void paint(Graphics g)\r
159     {\r
160       Dimension d = getSize();\r
161       if (isGcol)\r
162       {\r
163         if (isColourByLabel)\r
164         {\r
165           g.setColor(Color.white);\r
166           g.fillRect(d.width / 2, 0, d.width / 2, d.height);\r
167           g.setColor(Color.black);\r
168           Font f = new Font("Verdana", Font.PLAIN, 10);\r
169           g.setFont(f);\r
170           g.drawString(MessageManager.getString("label.label"), 0, 0);\r
171         }\r
172         else\r
173         {\r
174           g.setColor(maxCol);\r
175           g.fillRect(d.width / 2, 0, d.width / 2, d.height);\r
176 \r
177         }\r
178       }\r
179     }\r
180 \r
181   }\r
182 \r
183   boolean amendFeatures(final SequenceI[] sequences,\r
184           final SequenceFeature[] features, boolean newFeatures,\r
185           final AlignmentPanel ap)\r
186   {\r
187     JPanel bigPanel = new JPanel(new BorderLayout());\r
188     final JTextField name = new JTextField(16);\r
189     final JTextField source = new JTextField(16);\r
190     final JTextArea description = new JTextArea(3, 35);\r
191     final JTextField start = new JTextField(8);\r
192     final JTextField end = new JTextField(8);\r
193     final Choice overlaps;\r
194     JButton deleteButton = new JButton("Delete");\r
195     deleteFeature = false;\r
196 \r
197     colourPanel = new FeatureColourPanel();\r
198     colourPanel.setSize(110, 15);\r
199     final FeatureRenderer fr = this;\r
200 \r
201     JPanel panel = new JPanel(new GridLayout(3, 1));\r
202 \r
203     featureIndex = 0; // feature to be amended.\r
204     JPanel tmp;\r
205 \r
206     // /////////////////////////////////////\r
207     // /MULTIPLE FEATURES AT SELECTED RESIDUE\r
208     if (!newFeatures && features.length > 1)\r
209     {\r
210       panel = new JPanel(new GridLayout(4, 1));\r
211       tmp = new JPanel();\r
212       tmp.add(new JLabel("Select Feature: "));\r
213       overlaps = new Choice();\r
214       for (int i = 0; i < features.length; i++)\r
215       {\r
216         String item = features[i].getType() + "/" + features[i].getBegin()\r
217                 + "-" + features[i].getEnd();\r
218 \r
219         if (features[i].getFeatureGroup() != null)\r
220         {\r
221           item += " (" + features[i].getFeatureGroup() + ")";\r
222         }\r
223 \r
224         overlaps.addItem(item);\r
225       }\r
226 \r
227       tmp.add(overlaps);\r
228 \r
229       overlaps.addItemListener(new java.awt.event.ItemListener()\r
230       {\r
231         public void itemStateChanged(java.awt.event.ItemEvent e)\r
232         {\r
233           int index = overlaps.getSelectedIndex();\r
234           if (index != -1)\r
235           {\r
236             featureIndex = index;\r
237             name.setText(features[index].getType());\r
238             description.setText(features[index].getDescription());\r
239             source.setText(features[index].getFeatureGroup());\r
240             start.setText(features[index].getBegin() + "");\r
241             end.setText(features[index].getEnd() + "");\r
242 \r
243             SearchResults highlight = new SearchResults();\r
244             highlight.addResult(sequences[0], features[index].getBegin(),\r
245                     features[index].getEnd());\r
246 \r
247             ap.seqPanel.seqCanvas.highlightSearchResults(highlight);\r
248 \r
249           }\r
250           Object col = getFeatureStyle(name.getText());\r
251           if (col == null)\r
252           {\r
253             col = new UserColourScheme().createColourFromName(name\r
254                     .getText());\r
255           }\r
256 \r
257           colourPanel.updateColor(col);\r
258         }\r
259       });\r
260 \r
261       panel.add(tmp);\r
262     }\r
263     // ////////\r
264     // ////////////////////////////////////\r
265 \r
266     tmp = new JPanel();\r
267     panel.add(tmp);\r
268     tmp.add(new JLabel("Name: ", JLabel.RIGHT));\r
269     tmp.add(name);\r
270 \r
271     tmp = new JPanel();\r
272     panel.add(tmp);\r
273     tmp.add(new JLabel("Group: ", JLabel.RIGHT));\r
274     tmp.add(source);\r
275 \r
276     tmp = new JPanel();\r
277     panel.add(tmp);\r
278     tmp.add(new JLabel("Colour: ", JLabel.RIGHT));\r
279     tmp.add(colourPanel);\r
280 \r
281     bigPanel.add(panel, BorderLayout.NORTH);\r
282 \r
283     panel = new JPanel();\r
284     panel.add(new JLabel("Description: ", JLabel.RIGHT));\r
285     panel.add(new JScrollPane().add(description));\r
286 \r
287     if (!newFeatures)\r
288     {\r
289       bigPanel.add(panel, BorderLayout.SOUTH);\r
290 \r
291       panel = new JPanel();\r
292       panel.add(new JLabel(" Start:", JLabel.RIGHT));\r
293       panel.add(start);\r
294       panel.add(new JLabel("  End:", JLabel.RIGHT));\r
295       panel.add(end);\r
296       bigPanel.add(panel, BorderLayout.CENTER);\r
297     }\r
298     else\r
299     {\r
300       bigPanel.add(panel, BorderLayout.CENTER);\r
301     }\r
302 \r
303     if (lastFeatureAdded == null)\r
304     {\r
305       if (features[0].type != null)\r
306       {\r
307         lastFeatureAdded = features[0].type;\r
308       }\r
309       else\r
310       {\r
311         lastFeatureAdded = "feature_1";\r
312       }\r
313     }\r
314 \r
315     if (lastFeatureGroupAdded == null)\r
316     {\r
317       if (features[0].featureGroup != null)\r
318       {\r
319         lastFeatureGroupAdded = features[0].featureGroup;\r
320       }\r
321       else\r
322       {\r
323         lastFeatureAdded = "Jalview";\r
324       }\r
325     }\r
326 \r
327     String title = newFeatures ? MessageManager\r
328             .getString("label.create_new_sequence_features")\r
329             : MessageManager.formatMessage("label.amend_delete_features",\r
330                     new String[]\r
331                     { sequences[0].getName() });\r
332 \r
333     final JVDialog dialog = new JVDialog(ap.alignFrame, title, true, 385,\r
334             240);\r
335 \r
336     dialog.setMainPanel(bigPanel);\r
337 \r
338     if (newFeatures)\r
339     {\r
340       name.setText(lastFeatureAdded);\r
341       source.setText(lastFeatureGroupAdded);\r
342     }\r
343     else\r
344     {\r
345       dialog.ok.setLabel(MessageManager.getString("label.amend"));\r
346       dialog.buttonPanel.add(deleteButton, 1);\r
347       deleteButton.addActionListener(new ActionListener()\r
348       {\r
349         public void actionPerformed(ActionEvent evt)\r
350         {\r
351           deleteFeature = true;\r
352           dialog.setVisible(false);\r
353         }\r
354       });\r
355       name.setText(features[0].getType());\r
356       source.setText(features[0].getFeatureGroup());\r
357     }\r
358 \r
359     start.setText(features[0].getBegin() + "");\r
360     end.setText(features[0].getEnd() + "");\r
361     description.setText(features[0].getDescription());\r
362     Color col = getColour(name.getText());\r
363     if (col == null)\r
364     {\r
365       col = new UserColourScheme()\r
366               .createColourFromName(name.getText());\r
367     }\r
368     Object fcol = getFeatureStyle(name.getText());\r
369     // simply display the feature color in a box\r
370     colourPanel.updateColor(fcol);\r
371     dialog.setResizable(true);\r
372     // TODO: render the graduated color in the box.\r
373     colourPanel.addMouseListener(new java.awt.event.MouseAdapter()\r
374     {\r
375       public void mousePressed(java.awt.event.MouseEvent evt)\r
376       {\r
377         if (!colourPanel.isGcol)\r
378         {\r
379           new UserDefinedColours(fr, ap.alignFrame);\r
380         }\r
381         else\r
382         {\r
383           FeatureColourChooser fcc = new FeatureColourChooser(\r
384                   ap.alignFrame, name.getText());\r
385           dialog.transferFocus();\r
386         }\r
387       }\r
388     });\r
389     dialog.setVisible(true);\r
390 \r
391     FeaturesFile ffile = new FeaturesFile();\r
392 \r
393     if (dialog.accept)\r
394     {\r
395       // This ensures that the last sequence\r
396       // is refreshed and new features are rendered\r
397       lastSeq = null;\r
398       lastFeatureAdded = name.getText().trim();\r
399       lastFeatureGroupAdded = source.getText().trim();\r
400       lastDescriptionAdded = description.getText().replace('\n', ' ');\r
401     }\r
402 \r
403     if (lastFeatureGroupAdded != null && lastFeatureGroupAdded.length() < 1)\r
404     {\r
405       lastFeatureGroupAdded = null;\r
406     }\r
407 \r
408     if (!newFeatures)\r
409     {\r
410 \r
411       SequenceFeature sf = features[featureIndex];\r
412       if (dialog.accept)\r
413       {\r
414         sf.type = lastFeatureAdded;\r
415         sf.featureGroup = lastFeatureGroupAdded;\r
416         sf.description = lastDescriptionAdded;\r
417         if (!colourPanel.isGcol)\r
418         {\r
419           // update colour - otherwise its already done.\r
420           setColour(sf.type, colourPanel.getBackground());\r
421         }\r
422         try\r
423         {\r
424           sf.begin = Integer.parseInt(start.getText());\r
425           sf.end = Integer.parseInt(end.getText());\r
426         } catch (NumberFormatException ex)\r
427         {\r
428         }\r
429 \r
430         ffile.parseDescriptionHTML(sf, false);\r
431         setVisible(lastFeatureAdded); // if user edited name then make sure new\r
432                                       // type is visible\r
433       }\r
434       if (deleteFeature)\r
435       {\r
436         sequences[0].deleteFeature(sf);\r
437       }\r
438 \r
439     }\r
440     else\r
441     {\r
442       if (dialog.accept && name.getText().length() > 0)\r
443       {\r
444         for (int i = 0; i < sequences.length; i++)\r
445         {\r
446           features[i].type = lastFeatureAdded;\r
447           features[i].featureGroup = lastFeatureGroupAdded;\r
448           features[i].description = lastDescriptionAdded;\r
449           sequences[i].addSequenceFeature(features[i]);\r
450           ffile.parseDescriptionHTML(features[i], false);\r
451         }\r
452 \r
453         Color newColour = colourPanel.getBackground();\r
454         // setColour(lastFeatureAdded, fcol);\r
455 \r
456         if (lastFeatureGroupAdded != null)\r
457         {\r
458           setGroupVisibility(lastFeatureGroupAdded, true);\r
459         }\r
460         setColour(lastFeatureAdded, newColour); // was fcol\r
461         setVisible(lastFeatureAdded);\r
462         findAllFeatures(false); // different to original applet behaviour ?\r
463         // findAllFeatures();\r
464       }\r
465       else\r
466       {\r
467         // no update to the alignment\r
468         return false;\r
469       }\r
470     }\r
471     // refresh the alignment and the feature settings dialog\r
472     if (((AlignViewport) av).featureSettings != null)\r
473     {\r
474       ((AlignViewport) av).featureSettings.refreshTable();\r
475     }\r
476     // findAllFeatures();\r
477 \r
478     ap.paintAlignment(true);\r
479 \r
480     return true;\r
481   }\r
482 }\r