offy changes
[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(760, 370);\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         UserColourScheme ret = null;\r
340 \r
341         String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");\r
342         if ( colours != null )\r
343         {\r
344           if(colours.indexOf("|")>-1)\r
345             colours = colours.substring(0, colours.indexOf("|"));\r
346 \r
347           ret = loadColours(colours);\r
348         }\r
349 \r
350         if(ret == null)\r
351         {\r
352           Color[] newColours = new Color[24];\r
353           for (int i = 0; i < 24; i++)\r
354           {\r
355             newColours[i] = Color.white;\r
356           }\r
357           ret =  new UserColourScheme(newColours);\r
358         }\r
359 \r
360         return ret;\r
361     }\r
362 \r
363     /**\r
364      * DOCUMENT ME!\r
365      *\r
366      * @param file DOCUMENT ME!\r
367      *\r
368      * @return DOCUMENT ME!\r
369      */\r
370     static UserColourScheme loadColours(String file)\r
371     {\r
372          UserColourScheme ucs = null;\r
373          Color[]  newColours = null;\r
374 \r
375         try\r
376         {\r
377             InputStreamReader in = new InputStreamReader(new FileInputStream(\r
378                         file), "UTF-8");\r
379 \r
380             jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();\r
381             jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
382 \r
383             newColours = new Color[jucs.getColourCount()];\r
384 \r
385             for (int i = 0; i < 24; i++)\r
386             {\r
387               newColours[i] = new Color(Integer.parseInt(\r
388                   jucs.getColour(i).getRGB(), 16));\r
389             }\r
390             if (newColours != null)\r
391             {\r
392               ucs = new UserColourScheme(newColours);\r
393               ucs.setName( jucs.getSchemeName() );\r
394             }\r
395 \r
396         }\r
397         catch (Exception ex)\r
398         {\r
399             System.out.println("Error loading User ColourFile\n"+ex);\r
400         }\r
401 \r
402 \r
403        return ucs;\r
404     }\r
405 \r
406     /**\r
407      * DOCUMENT ME!\r
408      *\r
409      * @param e DOCUMENT ME!\r
410      */\r
411     protected void savebutton_actionPerformed(ActionEvent e)\r
412     {\r
413       if(schemeName.getText().trim().length()<1)\r
414       {\r
415         JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
416                                               "User colour scheme must have a name!",\r
417                                               "No name for colour scheme",\r
418                                               JOptionPane.WARNING_MESSAGE);\r
419         return;\r
420       }\r
421 \r
422       if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )\r
423       {\r
424         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."\r
425             +"\nContinue saving colour scheme as "+schemeName.getText()+"?",\r
426            "Duplicate scheme name", JOptionPane.YES_NO_OPTION);\r
427         if(reply != JOptionPane.YES_OPTION)\r
428           return;\r
429 \r
430          userColourSchemes.remove(schemeName.getText());\r
431       }\r
432         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
433                     "LAST_DIRECTORY"), new String[] { "jc" },\r
434                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
435 \r
436         chooser.setFileView(new jalview.io.JalviewFileView());\r
437         chooser.setDialogTitle("Save colour scheme");\r
438         chooser.setToolTipText("Save");\r
439 \r
440         int value = chooser.showSaveDialog(this);\r
441 \r
442         if (value == JalviewFileChooser.APPROVE_OPTION)\r
443         {\r
444             String choice = chooser.getSelectedFile().getPath();\r
445             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);\r
446             if(defaultColours.indexOf(choice)==-1)\r
447             {\r
448               if(defaultColours.length()>0)\r
449                 defaultColours = defaultColours.concat("|");\r
450               defaultColours = defaultColours.concat(choice);\r
451             }\r
452 \r
453             userColourSchemes.put(schemeName.getText(), getSchemeFromGUI());\r
454 \r
455             ap.alignFrame.updateUserColourMenu();\r
456 \r
457             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
458 \r
459             jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
460             ucs.setSchemeName(schemeName.getText());\r
461             try\r
462             {\r
463                 PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
464                             new FileOutputStream(choice), "UTF-8"));\r
465 \r
466                 for (int i = 0; i < 24; i++)\r
467                 {\r
468                     JButton button = (JButton) buttonPanel.getComponent(i);\r
469                     jalview.binding.Colour col = new jalview.binding.Colour();\r
470                     col.setName(button.getText());\r
471                     col.setRGB(jalview.util.Format.getHexString(\r
472                             button.getBackground()));\r
473                     ucs.addColour(col);\r
474                 }\r
475 \r
476                 ucs.marshal(out);\r
477                 out.close();\r
478             }\r
479             catch (Exception ex)\r
480             {\r
481                 ex.printStackTrace();\r
482             }\r
483         }\r
484     }\r
485 \r
486     /**\r
487      * DOCUMENT ME!\r
488      *\r
489      * @param e DOCUMENT ME!\r
490      */\r
491     protected void cancelButton_actionPerformed(ActionEvent e)\r
492     {\r
493         if (seqGroup != null)\r
494         {\r
495             seqGroup.cs = oldColourScheme;\r
496         }\r
497         else\r
498         {\r
499             ap.av.setGlobalColourScheme(oldColourScheme);\r
500         }\r
501 \r
502         ap.repaint();\r
503 \r
504         try\r
505         {\r
506             frame.setClosed(true);\r
507         }\r
508         catch (Exception ex)\r
509         {\r
510         }\r
511     }\r
512 \r
513 \r
514     static Hashtable userColourSchemes;\r
515 \r
516     public static Hashtable getUserColourSchemes()\r
517     {\r
518       return userColourSchemes;\r
519     }\r
520 \r
521     public static void initUserColourSchemes(String files)\r
522     {\r
523       userColourSchemes = new Hashtable();\r
524 \r
525       if(files==null || files.length()==0)\r
526         return;\r
527 \r
528 \r
529       // In case colours can't be loaded, we'll remove them\r
530       // from the default list here.\r
531       StringBuffer coloursFound = new StringBuffer();\r
532       StringTokenizer st = new StringTokenizer(files, "|");\r
533       while (st.hasMoreElements())\r
534       {\r
535         String file = st.nextToken();\r
536         try\r
537         {\r
538           UserColourScheme ucs = loadColours(file);\r
539           if (ucs != null)\r
540           {\r
541             if (coloursFound.length() > 0)\r
542               coloursFound.append("|");\r
543             coloursFound.append(file);\r
544             userColourSchemes.put(ucs.getName(), ucs);\r
545           }\r
546         }\r
547         catch (Exception ex)\r
548         {\r
549           System.out.println("Error loading User ColourFile\n" + ex);\r
550         }\r
551       }\r
552       if (!files.equals(coloursFound.toString()))\r
553       {\r
554         if (coloursFound.toString().length() > 1)\r
555           jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",\r
556                                         coloursFound.toString());\r
557         else\r
558           jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
559       }\r
560     }\r
561 \r
562     public static void removeColourFromDefaults(String target)\r
563     {\r
564       // The only way to find colours by name is to load them in\r
565       // In case colours can't be loaded, we'll remove them\r
566       // from the default list here.\r
567 \r
568       userColourSchemes = new Hashtable();\r
569 \r
570       StringBuffer coloursFound = new StringBuffer();\r
571       StringTokenizer st = new StringTokenizer(\r
572            jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");\r
573 \r
574       while (st.hasMoreElements())\r
575       {\r
576         String file = st.nextToken();\r
577         try\r
578         {\r
579           UserColourScheme ucs = loadColours(file);\r
580           if (ucs != null && !ucs.getName().equals(target))\r
581           {\r
582             if (coloursFound.length() > 0)\r
583               coloursFound.append("|");\r
584             coloursFound.append(file);\r
585             userColourSchemes.put(ucs.getName(), ucs);\r
586           }\r
587         }\r
588         catch (Exception ex)\r
589         {\r
590           System.out.println("Error loading User ColourFile\n" + ex);\r
591         }\r
592       }\r
593 \r
594       if (coloursFound.toString().length() > 1)\r
595         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());\r
596       else\r
597         jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
598 \r
599     }\r
600 }\r