c61db4b42f083bc6e53195f23d83b91f89840f26
[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 \r
56     /**\r
57      * Creates a new UserDefinedColours object.\r
58      *\r
59      * @param ap DOCUMENT ME!\r
60      * @param sg DOCUMENT ME!\r
61      */\r
62     public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)\r
63     {\r
64         super();\r
65         frame = new JInternalFrame();\r
66         frame.setContentPane(this);\r
67         Desktop.addInternalFrame(frame, "User Defined Colours", 720, 370, true);\r
68 \r
69         if (System.getProperty("os.name").startsWith("Mac"))\r
70         {\r
71             frame.setSize(450, 560);\r
72         }\r
73 \r
74         if (sg != null)\r
75         {\r
76             frame.setTitle(frame.getTitle() + " (" + sg.getName() + ")");\r
77         }\r
78 \r
79         colorChooser.getSelectionModel().addChangeListener(this);\r
80 \r
81         this.ap = ap;\r
82         seqGroup = sg;\r
83 \r
84         if (seqGroup != null)\r
85         {\r
86             oldColourScheme = seqGroup.cs;\r
87         }\r
88         else\r
89         {\r
90             oldColourScheme = ap.av.getGlobalColourScheme();\r
91         }\r
92 \r
93         if (oldColourScheme instanceof UserColourScheme)\r
94         {\r
95               schemeName.setText( ( (UserColourScheme) oldColourScheme).getName());\r
96         }\r
97         for (int i = 0; i < 20; i++)\r
98         {\r
99             makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) +\r
100                 "", ResidueProperties.aa[i]);\r
101         }\r
102 \r
103         makeButton("B", "B");\r
104         makeButton("Z", "Z");\r
105         makeButton("X", "X");\r
106         makeButton("Gap", "-");\r
107     }\r
108 \r
109     /**\r
110      * DOCUMENT ME!\r
111      *\r
112      * @param evt DOCUMENT ME!\r
113      */\r
114     public void stateChanged(ChangeEvent evt)\r
115     {\r
116         if (selectedButtons != null)\r
117         {\r
118           JButton button;\r
119           for(int i=0; i<selectedButtons.size(); i++)\r
120           {\r
121             button = (JButton)selectedButtons.elementAt(i);\r
122             button.setBackground(colorChooser.getColor());\r
123             button.setForeground( button.getBackground().brighter().brighter().brighter());\r
124           }\r
125         }\r
126     }\r
127 \r
128     /**\r
129      * DOCUMENT ME!\r
130      *\r
131      * @param e DOCUMENT ME!\r
132      */\r
133     public void colourButtonPressed(MouseEvent e)\r
134     {\r
135       if(selectedButtons == null)\r
136         selectedButtons = new Vector();\r
137 \r
138       JButton pressed = (JButton) e.getSource();\r
139 \r
140       if(e.isShiftDown())\r
141       {\r
142         JButton start = (JButton)selectedButtons.elementAt(selectedButtons.size()-1);\r
143         JButton end = (JButton) e.getSource();\r
144         int startIndex=0, endIndex=0;\r
145         for(int b=0; b<buttonPanel.getComponentCount(); b++)\r
146         {\r
147           if(buttonPanel.getComponent(b)==start)\r
148             startIndex = b;\r
149           if(buttonPanel.getComponent(b)==end)\r
150             endIndex = b;\r
151         }\r
152 \r
153         if(startIndex > endIndex)\r
154         {\r
155           int temp = startIndex;\r
156           startIndex = endIndex;\r
157           endIndex = temp;\r
158         }\r
159 \r
160         for(int b=startIndex; b<=endIndex; b++)\r
161         {\r
162           JButton button = (JButton)buttonPanel.getComponent(b);\r
163           if(!selectedButtons.contains(button))\r
164           {\r
165             button.setForeground(button.getBackground().brighter().brighter());\r
166             selectedButtons.add(button);\r
167           }\r
168         }\r
169       }\r
170       else if(!e.isControlDown())\r
171       {\r
172         for(int b=0; b<selectedButtons.size(); b++)\r
173         {\r
174           JButton button = (JButton)selectedButtons.elementAt(b);\r
175           button.setForeground(button.getBackground().darker().darker());\r
176         }\r
177         selectedButtons.clear();\r
178         pressed.setForeground( pressed.getBackground().brighter().brighter());\r
179         selectedButtons.addElement(pressed);\r
180 \r
181       }\r
182       else if(e.isControlDown())\r
183       {\r
184         if(selectedButtons.contains(pressed))\r
185         {\r
186           pressed.setForeground(pressed.getBackground().darker().darker());\r
187           selectedButtons.remove(pressed);\r
188         }\r
189         else\r
190         {\r
191           pressed.setForeground( pressed.getBackground().brighter().brighter());\r
192           selectedButtons.addElement(pressed);\r
193         }\r
194       }\r
195 \r
196       if(selectedButtons.size()>0)\r
197       colorChooser.setColor( ((JButton)selectedButtons.elementAt(0)).getBackground());\r
198     }\r
199 \r
200     /**\r
201      * DOCUMENT ME!\r
202      *\r
203      * @param label DOCUMENT ME!\r
204      * @param aa DOCUMENT ME!\r
205      */\r
206     void makeButton(String label, String aa)\r
207     {\r
208         final JButton button = new JButton();\r
209         Color col = Color.white;\r
210 \r
211         try\r
212         {\r
213             col = oldColourScheme.findColour(aa, -1);\r
214         }\r
215         catch (Exception ex)\r
216         {\r
217         //  ex.printStackTrace();\r
218         }\r
219 \r
220         button.setBackground(col);\r
221         button.setText(label);\r
222         button.setForeground(col.darker().darker().darker());\r
223         button.setFont(new java.awt.Font("Verdana", 1, 10));\r
224         button.addMouseListener(new java.awt.event.MouseAdapter()\r
225             {\r
226                 public void mouseClicked(MouseEvent e)\r
227                 {\r
228                     colourButtonPressed(e);\r
229                 }\r
230             });\r
231 \r
232         buttonPanel.add(button, null);\r
233     }\r
234 \r
235     /**\r
236      * DOCUMENT ME!\r
237      *\r
238      * @param e DOCUMENT ME!\r
239      */\r
240     protected void okButton_actionPerformed(ActionEvent e)\r
241     {\r
242         applyButton_actionPerformed(null);\r
243 \r
244         try\r
245         {\r
246             frame.setClosed(true);\r
247         }\r
248         catch (Exception ex)\r
249         {\r
250         }\r
251     }\r
252 \r
253     /**\r
254      * DOCUMENT ME!\r
255      *\r
256      * @param e DOCUMENT ME!\r
257      */\r
258     protected void applyButton_actionPerformed(ActionEvent e)\r
259     {\r
260         UserColourScheme ucs = getSchemeFromGUI();\r
261         ucs.setName(schemeName.getText());\r
262 \r
263         if (seqGroup != null)\r
264         {\r
265             seqGroup.cs = ucs;\r
266             ap.repaint();\r
267         }\r
268         else\r
269         {\r
270             ap.alignFrame.changeColour(ucs);\r
271         }\r
272     }\r
273 \r
274     UserColourScheme getSchemeFromGUI()\r
275     {\r
276       Color[] newColours = new Color[24];\r
277 \r
278       for (int i = 0; i < 24; i++)\r
279       {\r
280         JButton button = (JButton) buttonPanel.getComponent(i);\r
281         newColours[i] = button.getBackground();\r
282       }\r
283 \r
284       UserColourScheme ucs = new UserColourScheme(newColours);\r
285       ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());\r
286 \r
287       return ucs;\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 loadbutton_actionPerformed(ActionEvent e)\r
298     {\r
299         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
300                     "LAST_DIRECTORY"), new String[] { "jc" },\r
301                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
302         chooser.setFileView(new jalview.io.JalviewFileView());\r
303         chooser.setDialogTitle("Load colour scheme");\r
304         chooser.setToolTipText("Load");\r
305 \r
306         int value = chooser.showOpenDialog(this);\r
307 \r
308         if (value == JalviewFileChooser.APPROVE_OPTION)\r
309         {\r
310             File choice = chooser.getSelectedFile();\r
311             jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());\r
312             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS",\r
313                 choice.getPath());\r
314             if (defaultColours.indexOf(choice.getPath()) == -1)\r
315               defaultColours = defaultColours.concat("|").concat(choice.getPath());\r
316 \r
317             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
318 \r
319 \r
320             UserColourScheme ucs = loadColours(choice.getAbsolutePath());\r
321             Color[] colors = ucs.getColours();\r
322             schemeName.setText(ucs.getName());\r
323 \r
324             for (int i = 0; i < colors.length; i++)\r
325             {\r
326                 JButton button = (JButton) buttonPanel.getComponent(i);\r
327                 button.setBackground(colors[i]);\r
328             }\r
329         }\r
330     }\r
331 \r
332     /**\r
333      * DOCUMENT ME!\r
334      *\r
335      * @return DOCUMENT ME!\r
336      */\r
337     public static UserColourScheme loadDefaultColours()\r
338     {\r
339         String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");\r
340         if ( colours != null)\r
341         {\r
342           if(colours.indexOf("|")>-1)\r
343             colours = colours.substring(0, colours.indexOf("|"));\r
344 \r
345             return loadColours(colours);\r
346         }\r
347         else\r
348         {\r
349           Color[] newColours = new Color[24];\r
350           for (int i = 0; i < 24; i++)\r
351           {\r
352             newColours[i] = Color.white;\r
353           }\r
354           return new UserColourScheme(newColours);\r
355         }\r
356     }\r
357 \r
358     /**\r
359      * DOCUMENT ME!\r
360      *\r
361      * @param file DOCUMENT ME!\r
362      *\r
363      * @return DOCUMENT ME!\r
364      */\r
365     public static UserColourScheme loadColours(String file)\r
366     {\r
367          UserColourScheme ucs = null;\r
368          Color[]  newColours = null;\r
369 \r
370         try\r
371         {\r
372             InputStreamReader in = new InputStreamReader(new FileInputStream(\r
373                         file), "UTF-8");\r
374 \r
375             jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();\r
376             jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
377 \r
378             newColours = new Color[jucs.getColourCount()];\r
379 \r
380             for (int i = 0; i < 24; i++)\r
381             {\r
382               newColours[i] = new Color(Integer.parseInt(\r
383                   jucs.getColour(i).getRGB(), 16));\r
384             }\r
385             if (newColours != null)\r
386             {\r
387               ucs = new UserColourScheme(newColours);\r
388               ucs.setName( jucs.getSchemeName() );\r
389             }\r
390 \r
391         }\r
392         catch (Exception ex)\r
393         {\r
394             System.out.println("Error loading User ColourFile\n"+ex);\r
395         }\r
396 \r
397 \r
398        return ucs;\r
399     }\r
400 \r
401     /**\r
402      * DOCUMENT ME!\r
403      *\r
404      * @param e DOCUMENT ME!\r
405      */\r
406     protected void savebutton_actionPerformed(ActionEvent e)\r
407     {\r
408       if(schemeName.getText().trim().length()<1)\r
409       {\r
410         JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
411                                               "User colour scheme must have a name!",\r
412                                               "No name for colour scheme",\r
413                                               JOptionPane.WARNING_MESSAGE);\r
414         return;\r
415       }\r
416 \r
417       if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )\r
418       {\r
419         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."\r
420             +"\nContinue saving colour scheme as "+schemeName.getText()+"?",\r
421            "Duplicate scheme name", JOptionPane.YES_NO_OPTION);\r
422         if(reply != JOptionPane.YES_OPTION)\r
423           return;\r
424 \r
425          userColourSchemes.remove(schemeName.getText());\r
426       }\r
427         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
428                     "LAST_DIRECTORY"), new String[] { "jc" },\r
429                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
430 \r
431         chooser.setFileView(new jalview.io.JalviewFileView());\r
432         chooser.setDialogTitle("Save colour scheme");\r
433         chooser.setToolTipText("Save");\r
434 \r
435         int value = chooser.showSaveDialog(this);\r
436 \r
437         if (value == JalviewFileChooser.APPROVE_OPTION)\r
438         {\r
439             String choice = chooser.getSelectedFile().getPath();\r
440             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);\r
441             if(defaultColours.indexOf(choice)==-1)\r
442             {\r
443               if(defaultColours.length()<1)\r
444                 defaultColours = defaultColours.concat("|");\r
445               defaultColours = defaultColours.concat(choice);\r
446             }\r
447 \r
448             userColourSchemes.put(schemeName.getText(), getSchemeFromGUI());\r
449 \r
450             ap.alignFrame.updateUserColourMenu();\r
451 \r
452             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
453 \r
454             jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
455             ucs.setSchemeName(schemeName.getText());\r
456             try\r
457             {\r
458                 PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
459                             new FileOutputStream(choice), "UTF-8"));\r
460 \r
461                 for (int i = 0; i < 24; i++)\r
462                 {\r
463                     JButton button = (JButton) buttonPanel.getComponent(i);\r
464                     jalview.binding.Colour col = new jalview.binding.Colour();\r
465                     col.setName(button.getText());\r
466                     col.setRGB(jalview.util.Format.getHexString(\r
467                             button.getBackground()));\r
468                     ucs.addColour(col);\r
469                 }\r
470 \r
471                 ucs.marshal(out);\r
472                 out.close();\r
473             }\r
474             catch (Exception ex)\r
475             {\r
476                 ex.printStackTrace();\r
477             }\r
478         }\r
479     }\r
480 \r
481     /**\r
482      * DOCUMENT ME!\r
483      *\r
484      * @param e DOCUMENT ME!\r
485      */\r
486     protected void cancelButton_actionPerformed(ActionEvent e)\r
487     {\r
488         if (seqGroup != null)\r
489         {\r
490             seqGroup.cs = oldColourScheme;\r
491         }\r
492         else\r
493         {\r
494             ap.av.setGlobalColourScheme(oldColourScheme);\r
495         }\r
496 \r
497         ap.repaint();\r
498 \r
499         try\r
500         {\r
501             frame.setClosed(true);\r
502         }\r
503         catch (Exception ex)\r
504         {\r
505         }\r
506     }\r
507 \r
508 \r
509     static Hashtable userColourSchemes;\r
510 \r
511     public static Hashtable getUserColourSchemes()\r
512     {\r
513       return userColourSchemes;\r
514     }\r
515 \r
516     public static void initUserColourSchemes(String files)\r
517     {\r
518       userColourSchemes = new Hashtable();\r
519 \r
520       if(files==null)\r
521         return;\r
522 \r
523       // In case colours can't be loaded, we'll remove them\r
524       // from the default list here.\r
525       StringBuffer coloursFound = new StringBuffer();\r
526       StringTokenizer st = new StringTokenizer(files, "|");\r
527       while (st.hasMoreElements())\r
528       {\r
529         String file = st.nextToken();\r
530         try\r
531         {\r
532           UserColourScheme ucs = loadColours(file);\r
533           if (ucs != null)\r
534           {\r
535             if (coloursFound.length() > 0)\r
536               coloursFound.append("|");\r
537             coloursFound.append(file);\r
538             userColourSchemes.put(ucs.getName(), ucs);\r
539           }\r
540         }\r
541         catch (Exception ex)\r
542         {\r
543           System.out.println("Error loading User ColourFile\n" + ex);\r
544         }\r
545       }\r
546       if (!files.equals(coloursFound.toString()))\r
547       {\r
548         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());\r
549       }\r
550     }\r
551 }\r