JAL-1764 save Chimera/Jmol state as separate entries in project Jar
[jalview.git] / src / jalview / gui / StructureViewerBase.java
1 package jalview.gui;
2
3 import java.awt.Component;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Vector;
7
8 import javax.swing.JMenuItem;
9
10 import jalview.gui.StructureViewer.ViewerType;
11 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
12 import jalview.jbgui.GStructureViewer;
13
14 /**
15  * Base class with common functionality for JMol, Chimera or other structure
16  * viewers.
17  * 
18  * @author gmcarstairs
19  *
20  */
21 public abstract class StructureViewerBase extends GStructureViewer
22         implements Runnable, ViewSetProvider
23 {
24
25   /**
26    * list of sequenceSet ids associated with the view
27    */
28   protected List<String> _aps = new ArrayList<String>();
29   /**
30    * list of alignment panels to use for superposition
31    */
32   protected Vector<AlignmentPanel> _alignwith = new Vector<AlignmentPanel>();
33   /**
34    * list of alignment panels that are used for colouring structures by aligned
35    * sequences
36    */
37   protected Vector<AlignmentPanel> _colourwith = new Vector<AlignmentPanel>();
38   private String viewId = null;
39   private AlignmentPanel ap;
40
41   /**
42    * 
43    * @param ap2
44    * @return true if this Jmol instance is linked with the given alignPanel
45    */
46   public boolean isLinkedWith(AlignmentPanel ap2)
47   {
48     return _aps.contains(ap2.av.getSequenceSetId());
49   }
50
51   public boolean isUsedforaligment(AlignmentPanel ap2)
52   {
53   
54     return (_alignwith != null) && _alignwith.contains(ap2);
55   }
56
57   public boolean isUsedforcolourby(AlignmentPanel ap2)
58   {
59     return (_colourwith != null) && _colourwith.contains(ap2);
60   }
61
62   /**
63    * 
64    * @return TRUE if the view is NOT being coloured by the alignment colours.
65    */
66   public boolean isColouredByViewer()
67   {
68     return !getBinding().isColourBySequence();
69   }
70
71   public String getViewId()
72   {
73     if (viewId == null)
74     {
75       viewId = System.currentTimeMillis() + "." + this.hashCode();
76     }
77     return viewId;
78   }
79
80   protected void setViewId(String viewId)
81   {
82     this.viewId = viewId;
83   }
84
85   public abstract String getStateInfo();
86
87   protected void buildActionMenu()
88   {
89     if (_alignwith == null)
90     {
91       _alignwith = new Vector<AlignmentPanel>();
92     }
93     if (_alignwith.size() == 0 && ap != null)
94     {
95       _alignwith.add(ap);
96     }
97     ;
98     for (Component c : viewerActionMenu.getMenuComponents())
99     {
100       if (c != alignStructs)
101       {
102         viewerActionMenu.remove((JMenuItem) c);
103       }
104     }
105   }
106
107   public AlignmentPanel getAlignmentPanel()
108   {
109     return ap;
110   }
111
112   protected void setAlignmentPanel(AlignmentPanel alp)
113   {
114     this.ap = alp;
115   }
116
117   public AlignmentPanel[] getAllAlignmentPanels()
118   {
119     AlignmentPanel[] t, list = new AlignmentPanel[0];
120     for (String setid : _aps)
121     {
122       AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(setid);
123       if (panels != null)
124       {
125         t = new AlignmentPanel[list.length + panels.length];
126         System.arraycopy(list, 0, t, 0, list.length);
127         System.arraycopy(panels, 0, t, list.length, panels.length);
128         list = t;
129       }
130     }
131   
132     return list;
133   }
134
135   /**
136    * set the primary alignmentPanel reference and add another alignPanel to the
137    * list of ones to use for colouring and aligning
138    * 
139    * @param nap
140    */
141   public void addAlignmentPanel(AlignmentPanel nap)
142   {
143     if (getAlignmentPanel() == null)
144     {
145       setAlignmentPanel(nap);
146     }
147     if (!_aps.contains(nap.av.getSequenceSetId()))
148     {
149       _aps.add(nap.av.getSequenceSetId());
150     }
151   }
152
153   /**
154    * remove any references held to the given alignment panel
155    * 
156    * @param nap
157    */
158   public void removeAlignmentPanel(AlignmentPanel nap)
159   {
160     try
161     {
162       _alignwith.remove(nap);
163       _colourwith.remove(nap);
164       if (getAlignmentPanel() == nap)
165       {
166         setAlignmentPanel(null);
167         for (AlignmentPanel aps : getAllAlignmentPanels())
168         {
169           if (aps != nap)
170           {
171             setAlignmentPanel(aps);
172             break;
173           }
174         }
175       }
176     } catch (Exception ex)
177     {
178     }
179     if (getAlignmentPanel() != null)
180     {
181       buildActionMenu();
182     }
183   }
184
185   public void useAlignmentPanelForSuperposition(AlignmentPanel nap)
186   {
187     addAlignmentPanel(nap);
188     if (!_alignwith.contains(nap))
189     {
190       _alignwith.add(nap);
191     }
192   }
193
194   public void excludeAlignmentPanelForSuperposition(AlignmentPanel nap)
195   {
196     if (_alignwith.contains(nap))
197     {
198       _alignwith.remove(nap);
199     }
200   }
201
202   public void useAlignmentPanelForColourbyseq(AlignmentPanel nap, boolean enableColourBySeq)
203   {
204     useAlignmentPanelForColourbyseq(nap);
205     getBinding().setColourBySequence(enableColourBySeq);
206     seqColour.setSelected(enableColourBySeq);
207     viewerColour.setSelected(!enableColourBySeq);
208   }
209
210   public void useAlignmentPanelForColourbyseq(AlignmentPanel nap)
211   {
212     addAlignmentPanel(nap);
213     if (!_colourwith.contains(nap))
214     {
215       _colourwith.add(nap);
216     }
217   }
218
219   public void excludeAlignmentPanelForColourbyseq(AlignmentPanel nap)
220   {
221     if (_colourwith.contains(nap))
222     {
223       _colourwith.remove(nap);
224     }
225   }
226
227   public abstract ViewerType getViewerType();
228 }