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