if shift down bug fixed
[jalview.git] / src / jalview / gui / UserDefinedColours.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.io.*;\r
24 \r
25 import jalview.jbgui.*;\r
26 \r
27 import jalview.schemes.*;\r
28 \r
29 import java.awt.*;\r
30 import java.awt.event.*;\r
31 \r
32 import java.io.*;\r
33 \r
34 import java.util.*;\r
35 \r
36 import javax.swing.*;\r
37 import javax.swing.event.*;\r
38 \r
39 \r
40 \r
41 /**\r
42  * DOCUMENT ME!\r
43  *\r
44  * @author $author$\r
45  * @version $Revision$\r
46  */\r
47 public class UserDefinedColours extends GUserDefinedColours\r
48     implements ChangeListener\r
49 {\r
50     AlignmentPanel ap;\r
51     SequenceGroup seqGroup;\r
52     Vector selectedButtons;\r
53     ColourSchemeI oldColourScheme;\r
54     JInternalFrame frame;\r
55     MCview.PDBCanvas pdbcanvas;\r
56 \r
57     /**\r
58      * Creates a new UserDefinedColours object.\r
59      *\r
60      * @param ap DOCUMENT ME!\r
61      * @param sg DOCUMENT ME!\r
62      */\r
63     public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)\r
64     {\r
65         super();\r
66         frame = new JInternalFrame();\r
67         frame.setContentPane(this);\r
68         Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);\r
69 \r
70         if (System.getProperty("os.name").startsWith("Mac"))\r
71         {\r
72             frame.setSize(760, 370);\r
73         }\r
74 \r
75         if (sg != null)\r
76         {\r
77             frame.setTitle(frame.getTitle() + " (" + sg.getName() + ")");\r
78         }\r
79 \r
80         colorChooser.getSelectionModel().addChangeListener(this);\r
81 \r
82         this.ap = ap;\r
83         seqGroup = sg;\r
84 \r
85         if (seqGroup != null)\r
86         {\r
87             oldColourScheme = seqGroup.cs;\r
88         }\r
89         else\r
90         {\r
91             oldColourScheme = ap.av.getGlobalColourScheme();\r
92         }\r
93 \r
94         if (oldColourScheme instanceof UserColourScheme)\r
95         {\r
96               schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());\r
97         }\r
98         for (int i = 0; i < 20; i++)\r
99         {\r
100             makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
101                 "", ResidueProperties.aa[i]);\r
102         }\r
103 \r
104         makeButton("B", "B");\r
105         makeButton("Z", "Z");\r
106         makeButton("X", "X");\r
107         makeButton("Gap", "-");\r
108     }\r
109 \r
110     public UserDefinedColours(MCview.PDBCanvas pdb, ColourSchemeI oldcs)\r
111     {\r
112         super();\r
113         frame = new JInternalFrame();\r
114         frame.setContentPane(this);\r
115         Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);\r
116         pdbcanvas = pdb;\r
117 \r
118         if (System.getProperty("os.name").startsWith("Mac"))\r
119         {\r
120             frame.setSize(760, 370);\r
121         }\r
122 \r
123         colorChooser.getSelectionModel().addChangeListener(this);\r
124 \r
125         oldColourScheme = oldcs;\r
126 \r
127         if (oldColourScheme instanceof UserColourScheme)\r
128         {\r
129               schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());\r
130         }\r
131         for (int i = 0; i < 20; i++)\r
132         {\r
133             makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
134                 "", ResidueProperties.aa[i]);\r
135         }\r
136 \r
137         makeButton("B", "B");\r
138         makeButton("Z", "Z");\r
139         makeButton("X", "X");\r
140         makeButton("Gap", "-");\r
141     }\r
142 \r
143 \r
144     /**\r
145      * DOCUMENT ME!\r
146      *\r
147      * @param evt DOCUMENT ME!\r
148      */\r
149     public void stateChanged(ChangeEvent evt)\r
150     {\r
151         if (selectedButtons != null)\r
152         {\r
153           JButton button;\r
154           for(int i=0; i<selectedButtons.size(); i++)\r
155           {\r
156             button = (JButton)selectedButtons.elementAt(i);\r
157             button.setBackground(colorChooser.getColor());\r
158             button.setForeground( button.getBackground().brighter().brighter().brighter());\r
159           }\r
160         }\r
161     }\r
162 \r
163     /**\r
164      * DOCUMENT ME!\r
165      *\r
166      * @param e DOCUMENT ME!\r
167      */\r
168     public void colourButtonPressed(MouseEvent e)\r
169     {\r
170       if(selectedButtons == null)\r
171         selectedButtons = new Vector();\r
172 \r
173       JButton pressed = (JButton) e.getSource();\r
174 \r
175       if(e.isShiftDown())\r
176       {\r
177         JButton start, end = (JButton) e.getSource();\r
178         if(selectedButtons.size()>0)\r
179           start = (JButton)selectedButtons.elementAt(selectedButtons.size()-1);\r
180         else\r
181           start = (JButton) e.getSource();\r
182 \r
183         int startIndex=0, endIndex=0;\r
184         for(int b=0; b<buttonPanel.getComponentCount(); b++)\r
185         {\r
186           if(buttonPanel.getComponent(b)==start)\r
187             startIndex = b;\r
188           if(buttonPanel.getComponent(b)==end)\r
189             endIndex = b;\r
190         }\r
191 \r
192         if(startIndex > endIndex)\r
193         {\r
194           int temp = startIndex;\r
195           startIndex = endIndex;\r
196           endIndex = temp;\r
197         }\r
198 \r
199         for(int b=startIndex; b<=endIndex; b++)\r
200         {\r
201           JButton button = (JButton)buttonPanel.getComponent(b);\r
202           if(!selectedButtons.contains(button))\r
203           {\r
204             button.setForeground(button.getBackground().brighter().brighter());\r
205             selectedButtons.add(button);\r
206           }\r
207         }\r
208       }\r
209       else if(!e.isControlDown())\r
210       {\r
211         for(int b=0; b<selectedButtons.size(); b++)\r
212         {\r
213           JButton button = (JButton)selectedButtons.elementAt(b);\r
214           button.setForeground(button.getBackground().darker().darker());\r
215         }\r
216         selectedButtons.clear();\r
217         pressed.setForeground( pressed.getBackground().brighter().brighter());\r
218         selectedButtons.addElement(pressed);\r
219 \r
220       }\r
221       else if(e.isControlDown())\r
222       {\r
223         if(selectedButtons.contains(pressed))\r
224         {\r
225           pressed.setForeground(pressed.getBackground().darker().darker());\r
226           selectedButtons.remove(pressed);\r
227         }\r
228         else\r
229         {\r
230           pressed.setForeground( pressed.getBackground().brighter().brighter());\r
231           selectedButtons.addElement(pressed);\r
232         }\r
233       }\r
234 \r
235       if(selectedButtons.size()>0)\r
236       colorChooser.setColor( ((JButton)selectedButtons.elementAt(0)).getBackground());\r
237     }\r
238 \r
239     /**\r
240      * DOCUMENT ME!\r
241      *\r
242      * @param label DOCUMENT ME!\r
243      * @param aa DOCUMENT ME!\r
244      */\r
245     void makeButton(String label, String aa)\r
246     {\r
247         final JButton button = new JButton();\r
248         Color col = Color.white;\r
249 \r
250         try\r
251         {\r
252             col = oldColourScheme.findColour(aa, -1);\r
253         }\r
254         catch (Exception ex)\r
255         {\r
256         //  ex.printStackTrace();\r
257         }\r
258 \r
259         button.setBackground(col);\r
260         button.setText(label);\r
261         button.setForeground(col.darker().darker().darker());\r
262         button.setFont(new java.awt.Font("Verdana", 1, 10));\r
263         button.addMouseListener(new java.awt.event.MouseAdapter()\r
264             {\r
265                 public void mouseClicked(MouseEvent e)\r
266                 {\r
267                     colourButtonPressed(e);\r
268                 }\r
269             });\r
270 \r
271         buttonPanel.add(button, null);\r
272     }\r
273 \r
274     /**\r
275      * DOCUMENT ME!\r
276      *\r
277      * @param e DOCUMENT ME!\r
278      */\r
279     protected void okButton_actionPerformed(ActionEvent e)\r
280     {\r
281         applyButton_actionPerformed(null);\r
282 \r
283         try\r
284         {\r
285             frame.setClosed(true);\r
286         }\r
287         catch (Exception ex)\r
288         {\r
289         }\r
290     }\r
291 \r
292     /**\r
293      * DOCUMENT ME!\r
294      *\r
295      * @param e DOCUMENT ME!\r
296      */\r
297     protected void applyButton_actionPerformed(ActionEvent e)\r
298     {\r
299         UserColourScheme ucs = getSchemeFromGUI();\r
300         ucs.setName(schemeName.getText());\r
301 \r
302         if (seqGroup != null)\r
303         {\r
304             seqGroup.cs = ucs;\r
305             ap.repaint();\r
306         }\r
307         else if(ap!=null)\r
308         {\r
309             ap.alignFrame.changeColour(ucs);\r
310         }\r
311         else if(pdbcanvas!=null)\r
312         {\r
313           pdbcanvas.pdb.setColours(ucs);\r
314           pdbcanvas.updateSeqColours();\r
315         }\r
316     }\r
317 \r
318     UserColourScheme getSchemeFromGUI()\r
319     {\r
320       Color[] newColours = new Color[24];\r
321 \r
322       for (int i = 0; i < 24; i++)\r
323       {\r
324         JButton button = (JButton) buttonPanel.getComponent(i);\r
325         newColours[i] = button.getBackground();\r
326       }\r
327 \r
328       UserColourScheme ucs = new UserColourScheme(newColours);\r
329       if(ap!=null)\r
330         ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
331 \r
332 \r
333       return ucs;\r
334     }\r
335 \r
336 \r
337 \r
338     /**\r
339      * DOCUMENT ME!\r
340      *\r
341      * @param e DOCUMENT ME!\r
342      */\r
343     protected void loadbutton_actionPerformed(ActionEvent e)\r
344     {\r
345         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
346                     "LAST_DIRECTORY"), new String[] { "jc" },\r
347                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
348         chooser.setFileView(new jalview.io.JalviewFileView());\r
349         chooser.setDialogTitle("Load colour scheme");\r
350         chooser.setToolTipText("Load");\r
351 \r
352         int value = chooser.showOpenDialog(this);\r
353 \r
354         if (value == JalviewFileChooser.APPROVE_OPTION)\r
355         {\r
356             File choice = chooser.getSelectedFile();\r
357             jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());\r
358             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS",\r
359                 choice.getPath());\r
360             if (defaultColours.indexOf(choice.getPath()) == -1)\r
361               defaultColours = defaultColours.concat("|").concat(choice.getPath());\r
362 \r
363             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
364 \r
365 \r
366             UserColourScheme ucs = loadColours(choice.getAbsolutePath());\r
367             Color[] colors = ucs.getColours();\r
368             schemeName.setText(ucs.getName());\r
369 \r
370             for (int i = 0; i < colors.length; i++)\r
371             {\r
372                 JButton button = (JButton) buttonPanel.getComponent(i);\r
373                 button.setBackground(colors[i]);\r
374             }\r
375         }\r
376     }\r
377 \r
378     /**\r
379      * DOCUMENT ME!\r
380      *\r
381      * @return DOCUMENT ME!\r
382      */\r
383     public static UserColourScheme loadDefaultColours()\r
384     {\r
385         UserColourScheme ret = null;\r
386 \r
387         String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");\r
388         if ( colours != null )\r
389         {\r
390           if(colours.indexOf("|")>-1)\r
391             colours = colours.substring(0, colours.indexOf("|"));\r
392 \r
393           ret = loadColours(colours);\r
394         }\r
395 \r
396         if(ret == null)\r
397         {\r
398           Color[] newColours = new Color[24];\r
399           for (int i = 0; i < 24; i++)\r
400           {\r
401             newColours[i] = Color.white;\r
402           }\r
403           ret =  new UserColourScheme(newColours);\r
404         }\r
405 \r
406         return ret;\r
407     }\r
408 \r
409     /**\r
410      * DOCUMENT ME!\r
411      *\r
412      * @param file DOCUMENT ME!\r
413      *\r
414      * @return DOCUMENT ME!\r
415      */\r
416     static UserColourScheme loadColours(String file)\r
417     {\r
418          UserColourScheme ucs = null;\r
419          Color[]  newColours = null;\r
420 \r
421         try\r
422         {\r
423             InputStreamReader in = new InputStreamReader(new FileInputStream(\r
424                         file), "UTF-8");\r
425 \r
426             jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();\r
427             jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
428 \r
429             newColours = new Color[jucs.getColourCount()];\r
430 \r
431             for (int i = 0; i < 24; i++)\r
432             {\r
433               newColours[i] = new Color(Integer.parseInt(\r
434                   jucs.getColour(i).getRGB(), 16));\r
435             }\r
436             if (newColours != null)\r
437             {\r
438               ucs = new UserColourScheme(newColours);\r
439               ucs.setName( jucs.getSchemeName() );\r
440             }\r
441 \r
442         }\r
443         catch (Exception ex)\r
444         {\r
445             System.out.println("Error loading User ColourFile\n"+ex);\r
446         }\r
447 \r
448 \r
449        return ucs;\r
450     }\r
451 \r
452     /**\r
453      * DOCUMENT ME!\r
454      *\r
455      * @param e DOCUMENT ME!\r
456      */\r
457     protected void savebutton_actionPerformed(ActionEvent e)\r
458     {\r
459       if(schemeName.getText().trim().length()<1)\r
460       {\r
461         JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
462                                               "User colour scheme must have a name!",\r
463                                               "No name for colour scheme",\r
464                                               JOptionPane.WARNING_MESSAGE);\r
465         return;\r
466       }\r
467 \r
468       if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )\r
469       {\r
470         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."\r
471             +"\nContinue saving colour scheme as "+schemeName.getText()+"?",\r
472            "Duplicate scheme name", JOptionPane.YES_NO_OPTION);\r
473         if(reply != JOptionPane.YES_OPTION)\r
474           return;\r
475 \r
476          userColourSchemes.remove(schemeName.getText());\r
477       }\r
478         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
479                     "LAST_DIRECTORY"), new String[] { "jc" },\r
480                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
481 \r
482         chooser.setFileView(new jalview.io.JalviewFileView());\r
483         chooser.setDialogTitle("Save colour scheme");\r
484         chooser.setToolTipText("Save");\r
485 \r
486         int value = chooser.showSaveDialog(this);\r
487 \r
488         if (value == JalviewFileChooser.APPROVE_OPTION)\r
489         {\r
490             String choice = chooser.getSelectedFile().getPath();\r
491             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);\r
492             if(defaultColours.indexOf(choice)==-1)\r
493             {\r
494               if(defaultColours.length()>0)\r
495                 defaultColours = defaultColours.concat("|");\r
496               defaultColours = defaultColours.concat(choice);\r
497             }\r
498 \r
499             userColourSchemes.put(schemeName.getText(), getSchemeFromGUI());\r
500 \r
501             ap.alignFrame.updateUserColourMenu();\r
502 \r
503             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
504 \r
505             jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
506             ucs.setSchemeName(schemeName.getText());\r
507             try\r
508             {\r
509                 PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
510                             new FileOutputStream(choice), "UTF-8"));\r
511 \r
512                 for (int i = 0; i < 24; i++)\r
513                 {\r
514                     JButton button = (JButton) buttonPanel.getComponent(i);\r
515                     jalview.binding.Colour col = new jalview.binding.Colour();\r
516                     col.setName(button.getText());\r
517                     col.setRGB(jalview.util.Format.getHexString(\r
518                             button.getBackground()));\r
519                     ucs.addColour(col);\r
520                 }\r
521 \r
522                 ucs.marshal(out);\r
523                 out.close();\r
524             }\r
525             catch (Exception ex)\r
526             {\r
527                 ex.printStackTrace();\r
528             }\r
529         }\r
530     }\r
531 \r
532     /**\r
533      * DOCUMENT ME!\r
534      *\r
535      * @param e DOCUMENT ME!\r
536      */\r
537     protected void cancelButton_actionPerformed(ActionEvent e)\r
538     {\r
539       if (ap != null)\r
540       {\r
541         if (seqGroup != null)\r
542         {\r
543           seqGroup.cs = oldColourScheme;\r
544         }\r
545         else if (ap != null)\r
546         {\r
547           ap.av.setGlobalColourScheme(oldColourScheme);\r
548         }\r
549         ap.repaint();\r
550       }\r
551 \r
552       if(pdbcanvas!=null)\r
553       {\r
554         pdbcanvas.pdb.setColours(oldColourScheme);\r
555       }\r
556 \r
557         try\r
558         {\r
559             frame.setClosed(true);\r
560         }\r
561         catch (Exception ex)\r
562         {\r
563         }\r
564     }\r
565 \r
566 \r
567     static Hashtable userColourSchemes;\r
568 \r
569     public static Hashtable getUserColourSchemes()\r
570     {\r
571       return userColourSchemes;\r
572     }\r
573 \r
574     public static void initUserColourSchemes(String files)\r
575     {\r
576       userColourSchemes = new Hashtable();\r
577 \r
578       if(files==null || files.length()==0)\r
579         return;\r
580 \r
581 \r
582       // In case colours can't be loaded, we'll remove them\r
583       // from the default list here.\r
584       StringBuffer coloursFound = new StringBuffer();\r
585       StringTokenizer st = new StringTokenizer(files, "|");\r
586       while (st.hasMoreElements())\r
587       {\r
588         String file = st.nextToken();\r
589         try\r
590         {\r
591           UserColourScheme ucs = loadColours(file);\r
592           if (ucs != null)\r
593           {\r
594             if (coloursFound.length() > 0)\r
595               coloursFound.append("|");\r
596             coloursFound.append(file);\r
597             userColourSchemes.put(ucs.getName(), ucs);\r
598           }\r
599         }\r
600         catch (Exception ex)\r
601         {\r
602           System.out.println("Error loading User ColourFile\n" + ex);\r
603         }\r
604       }\r
605       if (!files.equals(coloursFound.toString()))\r
606       {\r
607         if (coloursFound.toString().length() > 1)\r
608           jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",\r
609                                         coloursFound.toString());\r
610         else\r
611           jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
612       }\r
613     }\r
614 \r
615     public static void removeColourFromDefaults(String target)\r
616     {\r
617       // The only way to find colours by name is to load them in\r
618       // In case colours can't be loaded, we'll remove them\r
619       // from the default list here.\r
620 \r
621       userColourSchemes = new Hashtable();\r
622 \r
623       StringBuffer coloursFound = new StringBuffer();\r
624       StringTokenizer st = new StringTokenizer(\r
625            jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");\r
626 \r
627       while (st.hasMoreElements())\r
628       {\r
629         String file = st.nextToken();\r
630         try\r
631         {\r
632           UserColourScheme ucs = loadColours(file);\r
633           if (ucs != null && !ucs.getName().equals(target))\r
634           {\r
635             if (coloursFound.length() > 0)\r
636               coloursFound.append("|");\r
637             coloursFound.append(file);\r
638             userColourSchemes.put(ucs.getName(), ucs);\r
639           }\r
640         }\r
641         catch (Exception ex)\r
642         {\r
643           System.out.println("Error loading User ColourFile\n" + ex);\r
644         }\r
645       }\r
646 \r
647       if (coloursFound.toString().length() > 1)\r
648         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());\r
649       else\r
650         jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
651 \r
652     }\r
653 }\r