update author list in license for (JAL-826)
[jalview.git] / src / jalview / javascript / MouseOverStructureListener.java
1 /*******************************************************************************
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
4  *
5  * This file is part of Jalview.
6  *
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  *******************************************************************************/
18 package jalview.javascript;\r
19 \r
20 import java.awt.Color;\r
21 import java.util.ArrayList;\r
22 \r
23 import jalview.api.AlignmentViewPanel;\r
24 import jalview.api.FeatureRenderer;\r
25 import jalview.api.SequenceRenderer;\r
26 import jalview.appletgui.AlignFrame;\r
27 import jalview.bin.JalviewLite;\r
28 import jalview.datamodel.SequenceI;\r
29 import jalview.ext.jmol.JmolCommands;\r
30 import jalview.structure.StructureListener;\r
31 import jalview.structure.StructureMapping;\r
32 import jalview.structure.StructureMappingcommandSet;\r
33 import jalview.structure.StructureSelectionManager;\r
34 \r
35 /**\r
36  * Propagate events involving PDB structures associated with sequences to a\r
37  * javascript function. Generally, the javascript handler is called with a\r
38  * series of arguments like (eventname, ... ). As of Jalview 2.7, the following\r
39  * different types of events are supported:\r
40  * <ul>\r
41  * <li>mouseover: javascript function called with arguments <pre>\r
42  * ['mouseover',String(pdb file URI), String(pdb file chain ID), String(residue\r
43  * number moused over), String(atom index corresponding to residue)]</pre></li>\r
44  * <li>colourstruct: javascript function called with arguments <pre>\r
45  * ['colourstruct',String(alignment view id),String(number of javascript message\r
46  * chunks to collect),String(length of first chunk in set of messages - or zero\r
47  * for null message)]</pre><br>\r
48  * The message contains a series of Jmol script commands that will colour\r
49  * structures according to their associated sequences in the current view. Use\r
50  * jalview\r
51  * .javascript.JalviewLiteJsApi.getJsMessage('colourstruct',String(alignment\r
52  * view id)) to retrieve successive chunks of the message.</li>\r
53  * </ul>\r
54  * \r
55  * @author Jim Procter (jprocter)\r
56  * \r
57  */\r
58 public class MouseOverStructureListener extends JSFunctionExec implements\r
59         JsCallBack, StructureListener\r
60 {\r
61 \r
62   String _listenerfn;\r
63 \r
64   String[] modelSet;\r
65 \r
66   public MouseOverStructureListener(JalviewLite jalviewLite,\r
67           String listener, String[] modelList)\r
68   {\r
69     super(jalviewLite);\r
70     _listenerfn = listener;\r
71     modelSet = modelList;\r
72     if (modelSet != null)\r
73     {\r
74       for (int i = 0; i < modelSet.length; i++)\r
75       {\r
76         // resolve a real filename\r
77         try\r
78         {\r
79           if (new java.net.URL(modelSet[i]).openConnection() != null)\r
80           {\r
81             continue;\r
82           }\r
83         } catch (Exception x)\r
84         {\r
85         }\r
86         ;\r
87         try\r
88         {\r
89           String db = jvlite.getDocumentBase().toString();\r
90           db = db.substring(0, db.lastIndexOf("/"));\r
91           if (new java.net.URL(db + "/" + modelSet[i]).openConnection() != null)\r
92           {\r
93             modelSet[i] = db + "/" + modelSet[i];\r
94             continue;\r
95           }\r
96         } catch (Exception x)\r
97         {\r
98         }\r
99         ;\r
100         try\r
101         {\r
102           if (new java.net.URL(jvlite.getCodeBase() + modelSet[i])\r
103                   .openConnection() != null)\r
104           {\r
105             modelSet[i] = jvlite.getCodeBase() + modelSet[i];\r
106             continue;\r
107           }\r
108         } catch (Exception x)\r
109         {\r
110         }\r
111         ;\r
112 \r
113       }\r
114     }\r
115   }\r
116 \r
117   @Override\r
118   public String[] getPdbFile()\r
119   {\r
120     return modelSet;\r
121   }\r
122 \r
123   @Override\r
124   public void mouseOverStructure(int atomIndex, String strInfo)\r
125   {\r
126 \r
127     // StructureSelectionManager.getStructureSelectionManager().mouseOverStructure(atomIndex,\r
128     // chain, pdbfile)\r
129     // TODO Auto-generated method stub\r
130 \r
131   }\r
132 \r
133   @Override\r
134   public void highlightAtom(int atomIndex, int pdbResNum, String chain,\r
135           String pdbId)\r
136   {\r
137     String[] st = new String[0];\r
138     try\r
139     {\r
140       executeJavascriptFunction(_listenerfn, st = new String[]\r
141       { "mouseover", "" + pdbId, "" + chain, "" + (pdbResNum),\r
142           "" + atomIndex });\r
143     } catch (Exception ex)\r
144     {\r
145       System.err.println("Couldn't execute callback with " + _listenerfn\r
146               + " using args { " + st[0] + ", " + st[1] + ", " + st[2]\r
147               + "," + st[3] + "\n");\r
148       ex.printStackTrace();\r
149 \r
150     }\r
151 \r
152   }\r
153 \r
154   @Override\r
155  public synchronized void updateColours(Object srce)\r
156   {\r
157     final Object source = srce;\r
158     StructureSelectionManager ssm = StructureSelectionManager\r
159             .getStructureSelectionManager(jvlite);\r
160     // if (jvlite.debug)\r
161     // {\r
162     // ssm.reportMapping();\r
163     // }\r
164     if (source instanceof jalview.api.AlignmentViewPanel)\r
165     {\r
166       SequenceI[][] sequence = new SequenceI[modelSet.length][];\r
167       for (int m = 0; m < modelSet.length; m++)\r
168       {\r
169         StructureMapping[] sm = ssm.getMapping(modelSet[m]);\r
170         if (sm != null && sm.length > 0)\r
171         {\r
172           sequence[m] = new SequenceI[sm.length];\r
173           for (int i = 0; i < sm.length; i++)\r
174           {\r
175             sequence[m][i] = sm[i].getSequence();\r
176           }\r
177         }\r
178         else\r
179         {\r
180           sequence[m] = new SequenceI[0];\r
181         }\r
182         // if (jvlite.debug)\r
183         // {\r
184         // System.err.println("Mapped '" + modelSet[m] + "' to "\r
185         // + sequence[m].length + " sequences.");\r
186         // }\r
187       }\r
188 \r
189       SequenceRenderer sr = ((jalview.appletgui.AlignmentPanel) source)\r
190               .getSequenceRenderer();\r
191       FeatureRenderer fr = ((jalview.appletgui.AlignmentPanel) source).av\r
192               .getShowSequenceFeatures() ? new jalview.appletgui.FeatureRenderer(\r
193               ((jalview.appletgui.AlignmentPanel) source).av) : null;\r
194       if (fr != null)\r
195       {\r
196         ((jalview.appletgui.FeatureRenderer) fr)\r
197                 .transferSettings(((jalview.appletgui.AlignmentPanel) source)\r
198                         .getFeatureRenderer());\r
199       }\r
200       ;\r
201 \r
202       \r
203       // Form a colour command from the given alignment panel for each distinct structure \r
204       ArrayList<String[]> ccomands=new ArrayList<String[]>();\r
205       ArrayList<String> pdbfn=new ArrayList<String>();\r
206       StructureMappingcommandSet[] colcommands=JmolCommands.getColourBySequenceCommand(\r
207               ssm, modelSet, sequence, sr, fr,\r
208               ((AlignmentViewPanel) source).getAlignment());\r
209       if (colcommands==null) {\r
210         return;\r
211       }\r
212       int sz=0;\r
213       for (jalview.structure.StructureMappingcommandSet ccset: colcommands) {\r
214         sz+=ccset.commands.length;\r
215         ccomands.add(ccset.commands);\r
216         pdbfn.add(ccset.mapping);\r
217       }\r
218       \r
219       String mclass,mhandle;\r
220       String ccomandset[] = new String[sz];\r
221       sz=0;\r
222       for (String[] ccset: ccomands) {\r
223         System.arraycopy(ccset, 0, ccomandset, sz, ccset.length);\r
224         sz+=ccset.length;\r
225       }\r
226       if (jvlite.isJsMessageSetChanged(mclass="colourstruct",mhandle=((jalview.appletgui.AlignmentPanel) source).av\r
227               .getViewId(), ccomandset)) {\r
228       jvlite.setJsMessageSet(mclass, mhandle , ccomandset);\r
229       // and notify javascript handler\r
230       String st[] = new String[]\r
231                                                   {\r
232               "colourstruct",\r
233               ""\r
234                       + ((jalview.appletgui.AlignmentPanel) source).av\r
235                               .getViewId(), ""+ccomandset.length, jvlite.arrayToSeparatorList(pdbfn.toArray(new String[pdbfn.size()]))\r
236                               };\r
237       try\r
238       {\r
239         executeJavascriptFunction(\r
240                 true,\r
241                 _listenerfn,st\r
242 );\r
243       } catch (Exception ex)\r
244       {\r
245         System.err.println("Couldn't execute callback with "\r
246                 + _listenerfn + " using args { " + st[0] + ", "\r
247                 + st[1] + ", " + st[2] + "," + st[3]+"}"); //  + ","+st[4]+"\n");\r
248         ex.printStackTrace();\r
249 \r
250       }\r
251       }\r
252 /*      new Thread(new Runnable()\r
253       {\r
254         public void run()\r
255         {\r
256           // and send to javascript handler\r
257           String st[] = new String[0];\r
258           int i = 0;\r
259           for (String colcommand : colcommands)\r
260           {\r
261             // do sync execution for each chunk\r
262             try\r
263             {\r
264               executeJavascriptFunction(\r
265                       false,\r
266                       _listenerfn,\r
267                       st = new String[]\r
268                       {\r
269                           "colourstruct",\r
270                           ""\r
271                                   + ((jalview.appletgui.AlignmentPanel) source).av\r
272                                           .getViewId(), handle, "" });\r
273             } catch (Exception ex)\r
274             {\r
275               System.err.println("Couldn't execute callback with "\r
276                       + _listenerfn + " using args { " + st[0] + ", "\r
277                       + st[1] + ", " + st[2] + "," + st[3] + "\n");\r
278               ex.printStackTrace();\r
279 \r
280             }\r
281           }\r
282         }\r
283       }).start();\r
284   */\r
285     }\r
286 \r
287   }\r
288 \r
289   @Override\r
290   public Color getColour(int atomIndex, int pdbResNum, String chain,\r
291           String pdbId)\r
292   {\r
293     return null;\r
294   }\r
295 \r
296   @Override\r
297   public AlignFrame getAlignFrame()\r
298   {\r
299     // associated with all alignframes, always.\r
300     return null;\r
301   }\r
302 \r
303   @Override\r
304   public String getListenerFunction()\r
305   {\r
306     return _listenerfn;\r
307   }\r
308 \r
309   public void finalise()\r
310   {\r
311     jvlite=null;\r
312     super.finalize();\r
313   }\r
314   @Override\r
315   public void releaseReferences(Object svl)\r
316   {\r
317     \r
318     // TODO Auto-generated method stub\r
319 \r
320   }\r
321 \r
322 }\r