Allow for scroller position
[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.schemabinding.version2.JalviewUserColours jucs\r
427                   = new jalview.schemabinding.version2.JalviewUserColours();\r
428 \r
429               org.exolab.castor.xml.Unmarshaller unmar\r
430                   = new org.exolab.castor.xml.Unmarshaller(jucs);\r
431               jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar.unmarshal( in );\r
432 \r
433               newColours = new Color[jucs.getColourCount()];\r
434 \r
435             for (int i = 0; i < 24; i++)\r
436             {\r
437               newColours[i] = new Color(Integer.parseInt(\r
438                   jucs.getColour(i).getRGB(), 16));\r
439             }\r
440             if (newColours != null)\r
441             {\r
442               ucs = new UserColourScheme(newColours);\r
443               ucs.setName( jucs.getSchemeName() );\r
444             }\r
445 \r
446         }\r
447         catch (Exception ex)\r
448         {\r
449             //Could be Archive Jalview format\r
450             try{\r
451               InputStreamReader in = new InputStreamReader(new FileInputStream(\r
452                   file), "UTF-8");\r
453 \r
454               jalview.binding.JalviewUserColours jucs\r
455                   = new jalview.binding.JalviewUserColours();\r
456 \r
457               jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
458 \r
459               newColours = new Color[jucs.getColourCount()];\r
460 \r
461               for (int i = 0; i < 24; i++)\r
462               {\r
463                 newColours[i] = new Color(Integer.parseInt(\r
464                     jucs.getColour(i).getRGB(), 16));\r
465               }\r
466               if (newColours != null)\r
467               {\r
468                 ucs = new UserColourScheme(newColours);\r
469                 ucs.setName(jucs.getSchemeName());\r
470               }\r
471             }catch(Exception ex2)\r
472             { ex2.printStackTrace(); }\r
473 \r
474             if(newColours==null)\r
475               System.out.println("Error loading User ColourFile\n"+ex);\r
476         }\r
477 \r
478        return ucs;\r
479     }\r
480 \r
481     /**\r
482      * DOCUMENT ME!\r
483      *\r
484      * @param e DOCUMENT ME!\r
485      */\r
486     protected void savebutton_actionPerformed(ActionEvent e)\r
487     {\r
488       if(schemeName.getText().trim().length()<1)\r
489       {\r
490         JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
491                                               "User colour scheme must have a name!",\r
492                                               "No name for colour scheme",\r
493                                               JOptionPane.WARNING_MESSAGE);\r
494         return;\r
495       }\r
496 \r
497       if(userColourSchemes!=null && userColourSchemes.containsKey(schemeName.getText()) )\r
498       {\r
499         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, "Colour scheme "+schemeName.getText()+ " exists."\r
500             +"\nContinue saving colour scheme as "+schemeName.getText()+"?",\r
501            "Duplicate scheme name", JOptionPane.YES_NO_OPTION);\r
502         if(reply != JOptionPane.YES_OPTION)\r
503           return;\r
504 \r
505          userColourSchemes.remove(schemeName.getText());\r
506       }\r
507         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
508                     "LAST_DIRECTORY"), new String[] { "jc" },\r
509                 new String[] { "Jalview User Colours" }, "Jalview User Colours");\r
510 \r
511         chooser.setFileView(new jalview.io.JalviewFileView());\r
512         chooser.setDialogTitle("Save colour scheme");\r
513         chooser.setToolTipText("Save");\r
514 \r
515         int value = chooser.showSaveDialog(this);\r
516 \r
517         if (value == JalviewFileChooser.APPROVE_OPTION)\r
518         {\r
519             String choice = chooser.getSelectedFile().getPath();\r
520             String defaultColours = jalview.bin.Cache.getDefault("USER_DEFINED_COLOURS", choice);\r
521             if(defaultColours.indexOf(choice)==-1)\r
522             {\r
523               if(defaultColours.length()>0)\r
524                 defaultColours = defaultColours.concat("|");\r
525               defaultColours = defaultColours.concat(choice);\r
526             }\r
527 \r
528             userColourSchemes.put(schemeName.getText(), getSchemeFromGUI());\r
529 \r
530             ap.alignFrame.updateUserColourMenu();\r
531 \r
532             jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);\r
533 \r
534             jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
535             ucs.setSchemeName(schemeName.getText());\r
536             try\r
537             {\r
538                 PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
539                             new FileOutputStream(choice), "UTF-8"));\r
540 \r
541                 for (int i = 0; i < 24; i++)\r
542                 {\r
543                     JButton button = (JButton) buttonPanel.getComponent(i);\r
544                     jalview.binding.Colour col = new jalview.binding.Colour();\r
545                     col.setName(button.getText());\r
546                     col.setRGB(jalview.util.Format.getHexString(\r
547                             button.getBackground()));\r
548                     ucs.addColour(col);\r
549                 }\r
550 \r
551                 ucs.marshal(out);\r
552                 out.close();\r
553             }\r
554             catch (Exception ex)\r
555             {\r
556                 ex.printStackTrace();\r
557             }\r
558         }\r
559     }\r
560 \r
561     /**\r
562      * DOCUMENT ME!\r
563      *\r
564      * @param e DOCUMENT ME!\r
565      */\r
566     protected void cancelButton_actionPerformed(ActionEvent e)\r
567     {\r
568       if (ap != null)\r
569       {\r
570         if (seqGroup != null)\r
571         {\r
572           seqGroup.cs = oldColourScheme;\r
573         }\r
574         else if (ap != null)\r
575         {\r
576           ap.av.setGlobalColourScheme(oldColourScheme);\r
577         }\r
578         ap.repaint();\r
579       }\r
580 \r
581       if(pdbcanvas!=null)\r
582       {\r
583         pdbcanvas.pdb.setColours(oldColourScheme);\r
584       }\r
585 \r
586         try\r
587         {\r
588             frame.setClosed(true);\r
589         }\r
590         catch (Exception ex)\r
591         {\r
592         }\r
593     }\r
594 \r
595 \r
596     static Hashtable userColourSchemes;\r
597 \r
598     public static Hashtable getUserColourSchemes()\r
599     {\r
600       return userColourSchemes;\r
601     }\r
602 \r
603     public static void initUserColourSchemes(String files)\r
604     {\r
605       userColourSchemes = new Hashtable();\r
606 \r
607       if(files==null || files.length()==0)\r
608         return;\r
609 \r
610 \r
611       // In case colours can't be loaded, we'll remove them\r
612       // from the default list here.\r
613       StringBuffer coloursFound = new StringBuffer();\r
614       StringTokenizer st = new StringTokenizer(files, "|");\r
615       while (st.hasMoreElements())\r
616       {\r
617         String file = st.nextToken();\r
618         try\r
619         {\r
620           UserColourScheme ucs = loadColours(file);\r
621           if (ucs != null)\r
622           {\r
623             if (coloursFound.length() > 0)\r
624               coloursFound.append("|");\r
625             coloursFound.append(file);\r
626             userColourSchemes.put(ucs.getName(), ucs);\r
627           }\r
628         }\r
629         catch (Exception ex)\r
630         {\r
631           System.out.println("Error loading User ColourFile\n" + ex);\r
632         }\r
633       }\r
634       if (!files.equals(coloursFound.toString()))\r
635       {\r
636         if (coloursFound.toString().length() > 1)\r
637           jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",\r
638                                         coloursFound.toString());\r
639         else\r
640           jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
641       }\r
642     }\r
643 \r
644     public static void removeColourFromDefaults(String target)\r
645     {\r
646       // The only way to find colours by name is to load them in\r
647       // In case colours can't be loaded, we'll remove them\r
648       // from the default list here.\r
649 \r
650       userColourSchemes = new Hashtable();\r
651 \r
652       StringBuffer coloursFound = new StringBuffer();\r
653       StringTokenizer st = new StringTokenizer(\r
654            jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");\r
655 \r
656       while (st.hasMoreElements())\r
657       {\r
658         String file = st.nextToken();\r
659         try\r
660         {\r
661           UserColourScheme ucs = loadColours(file);\r
662           if (ucs != null && !ucs.getName().equals(target))\r
663           {\r
664             if (coloursFound.length() > 0)\r
665               coloursFound.append("|");\r
666             coloursFound.append(file);\r
667             userColourSchemes.put(ucs.getName(), ucs);\r
668           }\r
669         }\r
670         catch (Exception ex)\r
671         {\r
672           System.out.println("Error loading User ColourFile\n" + ex);\r
673         }\r
674       }\r
675 \r
676       if (coloursFound.toString().length() > 1)\r
677         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());\r
678       else\r
679         jalview.bin.Cache.applicationProperties.remove("USER_DEFINED_COLOURS");\r
680 \r
681     }\r
682 }\r