formatting
[jalview.git] / src / jalview / gui / DasSourceBrowser.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle\r
4  * \r
5  * This file is part of Jalview.\r
6  * \r
7  * Jalview is free software: you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License \r
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
10  * \r
11  * Jalview is distributed in the hope that it will be useful, but \r
12  * WITHOUT ANY WARRANTY; without even the implied warranty \r
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
14  * PURPOSE.  See the GNU General Public License for more details.\r
15  * \r
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
17  */\r
18 package jalview.gui;\r
19 \r
20 import jalview.jbgui.GDasSourceBrowser;\r
21 import jalview.util.TableSorter;\r
22 import jalview.ws.dbsources.das.api.DasSourceRegistryI;\r
23 import jalview.ws.dbsources.das.api.jalviewSourceI;\r
24 \r
25 import java.awt.BorderLayout;\r
26 import java.awt.event.ActionEvent;\r
27 import java.awt.event.MouseAdapter;\r
28 import java.awt.event.MouseEvent;\r
29 import java.util.ArrayList;\r
30 import java.util.List;\r
31 import java.util.Properties;\r
32 import java.util.StringTokenizer;\r
33 import java.util.Vector;\r
34 \r
35 import javax.swing.JCheckBox;\r
36 import javax.swing.JLabel;\r
37 import javax.swing.JOptionPane;\r
38 import javax.swing.JPanel;\r
39 import javax.swing.JTextField;\r
40 import javax.swing.ListSelectionModel;\r
41 import javax.swing.SwingUtilities;\r
42 import javax.swing.event.ListSelectionEvent;\r
43 import javax.swing.event.ListSelectionListener;\r
44 import javax.swing.table.AbstractTableModel;\r
45 \r
46 import org.biodas.jdas.schema.sources.CAPABILITY;\r
47 import org.biodas.jdas.schema.sources.COORDINATES;\r
48 import org.biodas.jdas.schema.sources.PROP;\r
49 import org.biodas.jdas.schema.sources.VERSION;\r
50 \r
51 public class DasSourceBrowser extends GDasSourceBrowser implements\r
52         Runnable, ListSelectionListener\r
53 {\r
54   DasSourceRegistryI sourceRegistry = null;\r
55 \r
56   Vector<String> selectedSources;\r
57 \r
58   public DasSourceBrowser(FeatureSettings featureSettings)\r
59   {\r
60     fs = featureSettings;\r
61     // TODO DasSourceRegistryProvider API\r
62     sourceRegistry = jalview.bin.Cache.getDasSourceRegistry();\r
63     String registry = sourceRegistry.getDasRegistryURL();\r
64 \r
65     registryURL.setText(registry);\r
66 \r
67     setSelectedFromProperties();\r
68 \r
69     displayFullDetails(null);\r
70     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
71 \r
72     filter1.addListSelectionListener(this);\r
73     filter2.addListSelectionListener(this);\r
74     filter3.addListSelectionListener(this);\r
75 \r
76     // Ask to be notified of selection changes.\r
77     ListSelectionModel rowSM = table.getSelectionModel();\r
78     rowSM.addListSelectionListener(new ListSelectionListener()\r
79     {\r
80       public void valueChanged(ListSelectionEvent e)\r
81       {\r
82         ListSelectionModel lsm = (ListSelectionModel) e.getSource();\r
83         if (!lsm.isSelectionEmpty())\r
84         {\r
85           int selectedRow = lsm.getMinSelectionIndex();\r
86           displayFullDetails(table.getValueAt(selectedRow, 0).toString());\r
87         }\r
88       }\r
89     });\r
90 \r
91     table.addMouseListener(new MouseAdapter()\r
92     {\r
93       public void mouseClicked(MouseEvent evt)\r
94       {\r
95         if (evt.getClickCount() == 2\r
96                 || SwingUtilities.isRightMouseButton(evt))\r
97         {\r
98           editRemoveLocalSource(evt);\r
99         }\r
100       }\r
101     });\r
102 \r
103     if (sourceRegistry.getSources() != null)\r
104     {\r
105       init();\r
106     }\r
107   }\r
108 \r
109   FeatureSettings fs = null;\r
110 \r
111   private boolean loadingDasSources;\r
112 \r
113   public DasSourceBrowser()\r
114   {\r
115     this(null);\r
116   }\r
117 \r
118   public void paintComponent(java.awt.Graphics g)\r
119   {\r
120     if (sourceRegistry == null)\r
121     {\r
122       Thread worker = new Thread(this);\r
123       worker.start();\r
124     }\r
125   }\r
126 \r
127   void init()\r
128   {\r
129     List<jalviewSourceI> sources = sourceRegistry.getSources();\r
130     int dSize = sources.size();\r
131     Object[][] data = new Object[dSize][2];\r
132     for (int i = 0; i < dSize; i++)\r
133     {\r
134       data[i][0] = sources.get(i).getTitle(); // what's equivalent of nickname\r
135       data[i][1] = new Boolean(selectedSources.contains(sources.get(i)\r
136               .getTitle()));\r
137     }\r
138 \r
139     refreshTableData(data);\r
140     setCapabilities(sourceRegistry);\r
141 \r
142     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
143     {\r
144       public void run()\r
145       {\r
146         TableSorter sorter = (TableSorter) table.getModel();\r
147         sorter.setSortingStatus(1, TableSorter.DESCENDING);\r
148         sorter.setSortingStatus(1, TableSorter.NOT_SORTED);\r
149       }\r
150     });\r
151 \r
152     progressBar.setIndeterminate(false);\r
153     progressBar.setVisible(false);\r
154     addLocal.setVisible(true);\r
155     refresh.setVisible(true);\r
156   }\r
157 \r
158   public void refreshTableData(Object[][] data)\r
159   {\r
160     TableSorter sorter = new TableSorter(new DASTableModel(data));\r
161     sorter.setTableHeader(table.getTableHeader());\r
162     table.setModel(sorter);\r
163   }\r
164 \r
165   void displayFullDetails(String nickName)\r
166   {\r
167 \r
168     StringBuffer text = new StringBuffer(\r
169             "<HTML><font size=\"2\" face=\"Verdana, Arial, Helvetica, sans-serif\">");\r
170 \r
171     if (nickName == null)\r
172     {\r
173       fullDetails.setText(text + "Select a DAS service from the table"\r
174               + " to read a full description here.</font></html>");\r
175       return;\r
176     }\r
177 \r
178     int dSize = sourceRegistry.getSources().size();\r
179     for (jalviewSourceI ds : sourceRegistry.getSources())\r
180     {\r
181       if (!ds.getTitle().equals(nickName))\r
182       {\r
183         continue;\r
184       }\r
185 \r
186       VERSION latest = ds.getVersion();\r
187       text.append("<font color=\"#0000FF\">Id:</font> " + ds.getUri()\r
188               + "<br>");\r
189       text.append("<font color=\"#0000FF\">Nickname:</font> "\r
190               + ds.getTitle() + "<br>");\r
191 \r
192       text.append("<font color=\"#0000FF\">URL:</font> <a href=\""\r
193               + ds.getSourceURL() + "\">" + ds.getSourceURL() + "</a>"\r
194               + "<br>");\r
195       if (!ds.isLocal())\r
196       {\r
197         if (ds.getDocHref() != null && ds.getDocHref().length() > 0)\r
198         {\r
199           text.append("<font color=\"#0000FF\">Site:</font> <a href=\""\r
200                   + ds.getDocHref() + "\">" + ds.getDocHref() + "</a>"\r
201                   + "<br>");\r
202         }\r
203 \r
204         text.append("<font color=\"#0000FF\">Description:</font> "\r
205                 + ds.getDescription() + "<br>");\r
206 \r
207         text.append("<font color=\"#0000FF\">Admin Email:</font> <a href=\"mailto:"\r
208                 + ds.getEmail() + "\">" + ds.getEmail() + "</a>" + "<br>");\r
209 \r
210         text.append("<font color=\"#0000FF\">Registered at:</font> "\r
211                 + latest.getCreated() + "<br>");\r
212 \r
213         // TODO: Identify last successful test date\r
214         // text.append("<font color=\"#0000FF\">Last successful test:</font> "\r
215         // + latest.dasSources[i].getLeaseDate() + "<br>");\r
216       }\r
217       else\r
218       {\r
219         text.append("Source was added manually.<br/>");\r
220       }\r
221       text.append("<font color=\"#0000FF\">Labels:</font> ");\r
222       boolean b = false;\r
223       for (PROP labl : latest.getPROP())\r
224       {\r
225         if (labl.getName().equalsIgnoreCase("LABEL"))\r
226         {\r
227           if (b)\r
228           {\r
229             text.append(",");\r
230           }\r
231           text.append(" ");\r
232 \r
233           text.append(labl.getValue());\r
234           b = true;\r
235         }\r
236         ;\r
237       }\r
238       text.append("<br>");\r
239 \r
240       text.append("<font color=\"#0000FF\">Capabilities:</font> ");\r
241       CAPABILITY[] scap = latest.getCAPABILITY().toArray(new CAPABILITY[0]);\r
242       for (int j = 0; j < scap.length; j++)\r
243       {\r
244         text.append(scap[j].getType());\r
245         if (j < scap.length - 1)\r
246         {\r
247           text.append(", ");\r
248         }\r
249       }\r
250       text.append("<br>");\r
251 \r
252       text.append("<font color=\"#0000FF\">Coordinates:</font>");\r
253       int i = 1;\r
254       for (COORDINATES dcs : latest.getCOORDINATES())\r
255       {\r
256         text.append("<br/>" + i++ + ". ");\r
257         text.append(dcs.getAuthority() + " : " + dcs.getSource());\r
258         if (dcs.getTaxid() != null && dcs.getTaxid().trim().length() > 0)\r
259         {\r
260           text.append(" [TaxId:" + dcs.getTaxid() + "]");\r
261         }\r
262         if (dcs.getVersion() != null\r
263                 && dcs.getVersion().trim().length() > 0)\r
264         {\r
265           {\r
266             text.append(" {v. " + dcs.getVersion() + "}");\r
267           }\r
268         }\r
269         text.append(" (<a href=\"" + dcs.getUri() + "\">" + dcs.getUri()\r
270                 + "</a>)");\r
271       }\r
272       text.append("</font></html>");\r
273 \r
274       break;\r
275     }\r
276 \r
277     fullDetails.setText(text.toString());\r
278     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
279     {\r
280       public void run()\r
281       {\r
282         fullDetailsScrollpane.getVerticalScrollBar().setValue(0);\r
283       }\r
284     });\r
285   }\r
286 \r
287   public void run()\r
288   {\r
289     loadingDasSources = true;\r
290 \r
291     addLocal.setVisible(false);\r
292     refresh.setVisible(false);\r
293     progressBar.setVisible(true);\r
294     progressBar.setIndeterminate(true);\r
295     setParentGuiEnabled(false);\r
296     // Refresh the source list.\r
297     sourceRegistry.refreshSources();\r
298 \r
299     init();\r
300 \r
301     setParentGuiEnabled(true);\r
302     loadingDasSources = false;\r
303 \r
304   }\r
305 \r
306   private void setParentGuiEnabled(boolean b)\r
307   {\r
308     if (fs != null)\r
309     {\r
310       fs.fetchDAS.setEnabled(b);\r
311       fs.saveDAS.setEnabled(b);\r
312     }\r
313   }\r
314 \r
315   public Vector<jalviewSourceI> getSelectedSources()\r
316   {\r
317     // wait around if we're still loading.\r
318     while (sourceRegistry == null)\r
319     {\r
320       if (!loadingDasSources)\r
321       {\r
322         new Thread(this).start();\r
323         try\r
324         {\r
325           Thread.sleep(5);\r
326         } catch (Exception e)\r
327         {\r
328         }\r
329         ;\r
330         while (loadingDasSources)\r
331         {\r
332           try\r
333           {\r
334             Thread.sleep(5);\r
335           } catch (Exception e)\r
336           {\r
337           }\r
338           ;\r
339         }\r
340         ;\r
341       }\r
342     }\r
343 \r
344     Vector<jalviewSourceI> selected = new Vector<jalviewSourceI>();\r
345     for (String source : selectedSources)\r
346     {\r
347       jalviewSourceI srce = sourceRegistry.getSource(source);\r
348       if (srce != null)\r
349       {\r
350         selected.addElement(srce);\r
351       }\r
352     }\r
353     return selected;\r
354   }\r
355 \r
356   public void refresh_actionPerformed(ActionEvent e)\r
357   {\r
358     saveProperties(jalview.bin.Cache.applicationProperties);\r
359 \r
360     Thread worker = new Thread(this);\r
361     worker.start();\r
362   }\r
363 \r
364   private void setCapabilities(DasSourceRegistryI sourceRegistry2)\r
365   {\r
366     Vector<String> authority = new Vector<String>();\r
367     Vector<String> type = new Vector<String>();\r
368     Vector<String> label = new Vector<String>();\r
369     Vector<String> taxIds = new Vector<String>();\r
370     authority.add("Any");\r
371     type.add("Any");\r
372     label.add("Any");\r
373 \r
374     for (jalviewSourceI ds : sourceRegistry2.getSources())\r
375     {\r
376       VERSION latest = ds.getVersion();\r
377 \r
378       for (COORDINATES cs : latest.getCOORDINATES())\r
379       {\r
380         if (!type.contains(cs.getSource()))\r
381         {\r
382           type.add(cs.getSource()); // source==category\r
383         }\r
384 \r
385         if (!authority.contains(cs.getAuthority()))\r
386         {\r
387           authority.add(cs.getAuthority());\r
388         }\r
389       }\r
390 \r
391       for (PROP slabel : latest.getPROP())\r
392       {\r
393         if (slabel.getName().equalsIgnoreCase("LABEL")\r
394                 && !label.contains(slabel.getValue()))\r
395         {\r
396           label.add(slabel.getValue());\r
397         }\r
398       }\r
399 \r
400     }\r
401 \r
402     filter1.setListData(authority);\r
403     filter2.setListData(type);\r
404     filter3.setListData(label);\r
405     // filter4 taxIds\r
406 \r
407     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
408     {\r
409       public void run()\r
410       {\r
411         filter1.setSelectedIndex(0);\r
412         filter2.setSelectedIndex(0);\r
413         filter3.setSelectedIndex(0);\r
414       }\r
415     });\r
416   }\r
417 \r
418   public void amendLocal(boolean newSource)\r
419   {\r
420     String url = "http://localhost:8080/", nickname = "";\r
421     boolean seqsrc = false;\r
422     if (!newSource)\r
423     {\r
424       int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
425       nickname = table.getValueAt(selectedRow, 0).toString();\r
426       jalviewSourceI source = sourceRegistry.getSource(nickname);\r
427       url = source.getUri();\r
428       seqsrc = source.isSequenceSource();\r
429     }\r
430 \r
431     JTextField nametf = new JTextField(nickname, 40);\r
432     JTextField urltf = new JTextField(url, 40);\r
433     JCheckBox seqs = new JCheckBox("Sequence Source");\r
434     seqs.setSelected(seqsrc);\r
435     JPanel panel = new JPanel(new BorderLayout());\r
436     JPanel pane12 = new JPanel(new BorderLayout());\r
437     pane12.add(new JLabel("Nickname: "), BorderLayout.CENTER);\r
438     pane12.add(nametf, BorderLayout.EAST);\r
439     panel.add(pane12, BorderLayout.NORTH);\r
440     pane12 = new JPanel(new BorderLayout());\r
441     pane12.add(new JLabel("URL: "), BorderLayout.NORTH);\r
442     pane12.add(seqs, BorderLayout.SOUTH);\r
443     pane12.add(urltf, BorderLayout.EAST);\r
444     panel.add(pane12, BorderLayout.SOUTH);\r
445 \r
446     int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
447             panel, "Enter Nickname & URL of Local DAS Source",\r
448             JOptionPane.OK_CANCEL_OPTION);\r
449 \r
450     if (reply != JOptionPane.OK_OPTION)\r
451     {\r
452       return;\r
453     }\r
454 \r
455     if (!urltf.getText().endsWith("/"))\r
456     {\r
457       urltf.setText(urltf.getText() + "/");\r
458     }\r
459 \r
460     jalviewSourceI local = sourceRegistry.createLocalSource(\r
461             urltf.getText(), nametf.getText(), seqs.isSelected(), true);\r
462     List sources = sourceRegistry.getSources();\r
463     int osize = sources.size();\r
464     int size = osize + (newSource ? 1 : 0);\r
465 \r
466     Object[][] data = new Object[size][2];\r
467     DASTableModel dtm = (table != null) ? (DASTableModel) ((TableSorter) table\r
468             .getModel()).getTableModel() : null;\r
469     for (int i = 0; i < osize; i++)\r
470     {\r
471       String osrc = (dtm == null || i >= osize) ? null : (String) dtm\r
472               .getValueAt(i, 0);\r
473       if (!newSource && osrc != null\r
474               && dtm.getValueAt(i, 0).equals(nickname))\r
475       {\r
476         data[i][0] = local.getTitle();\r
477         data[i][1] = new Boolean(true);\r
478       }\r
479       else\r
480       {\r
481         data[i][0] = osrc;\r
482         data[i][1] = new Boolean(selectedSources.contains(osrc));\r
483       }\r
484     }\r
485     // Always add a new source at the end\r
486     if (newSource)\r
487     {\r
488       data[osize][0] = local.getTitle();\r
489       data[osize][1] = new Boolean(true);\r
490       selectedSources.add(local.getTitle());\r
491     }\r
492 \r
493     refreshTableData(data);\r
494 \r
495     SwingUtilities.invokeLater(new Runnable()\r
496     {\r
497       public void run()\r
498       {\r
499         scrollPane.getVerticalScrollBar().setValue(\r
500                 scrollPane.getVerticalScrollBar().getMaximum());\r
501       }\r
502     });\r
503 \r
504     displayFullDetails(local.getTitle());\r
505   }\r
506 \r
507   public void editRemoveLocalSource(MouseEvent evt)\r
508   {\r
509     int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
510     if (selectedRow == -1)\r
511     {\r
512       return;\r
513     }\r
514 \r
515     String nickname = table.getValueAt(selectedRow, 0).toString();\r
516 \r
517     if (!sourceRegistry.getSource(nickname).isLocal())\r
518     {\r
519       JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
520               "You can only edit or remove local DAS Sources!",\r
521               "Public DAS source - not editable",\r
522               JOptionPane.WARNING_MESSAGE);\r
523       return;\r
524     }\r
525 \r
526     Object[] options =\r
527     { "Edit", "Remove", "Cancel" };\r
528     int choice = JOptionPane.showInternalOptionDialog(Desktop.desktop,\r
529             "Do you want to edit or remove " + nickname + "?",\r
530             "Edit / Remove Local DAS Source",\r
531             JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,\r
532             null, options, options[2]);\r
533 \r
534     switch (choice)\r
535     {\r
536     case 0:\r
537       amendLocal(false);\r
538       break;\r
539     case 1:\r
540       sourceRegistry.removeLocalSource(sourceRegistry.getSource(nickname));\r
541       selectedSources.remove(nickname);\r
542       Object[][] data = new Object[sourceRegistry.getSources().size()][2];\r
543       int index = 0,\r
544       l = table.getRowCount();\r
545 \r
546       for (int i = 0; i < l; i++)\r
547       {\r
548         String nm;\r
549         if ((nm = (String) table.getValueAt(i, 0)).equals(nickname))\r
550         {\r
551           continue;\r
552         }\r
553         else\r
554         {\r
555           data[index][0] = nm;\r
556           data[index][1] = new Boolean(selectedSources.contains(nm));\r
557           index++;\r
558         }\r
559       }\r
560       refreshTableData(data);\r
561       SwingUtilities.invokeLater(new Runnable()\r
562       {\r
563         public void run()\r
564         {\r
565           scrollPane.getVerticalScrollBar().setValue(\r
566                   scrollPane.getVerticalScrollBar().getMaximum());\r
567         }\r
568       });\r
569 \r
570       break;\r
571     }\r
572   }\r
573 \r
574   public void valueChanged(ListSelectionEvent evt)\r
575   {\r
576     // Called when the MainTable selection changes\r
577     if (evt.getValueIsAdjusting())\r
578     {\r
579       return;\r
580     }\r
581 \r
582     displayFullDetails(null);\r
583 \r
584     // Filter the displayed data sources\r
585 \r
586     ArrayList names = new ArrayList();\r
587     ArrayList selected = new ArrayList();\r
588 \r
589     // The features filter is not visible, but we must still\r
590     // filter the das source list here.\r
591     // July 2006 - only 6 sources fo not serve features\r
592     Object[] dummyFeatureList = new Object[]\r
593     { "features" };\r
594     List<jalviewSourceI> srcs = sourceRegistry.getSources();\r
595     for (jalviewSourceI ds : srcs)\r
596     {\r
597 \r
598       VERSION v = ds.getVersion();\r
599       List<COORDINATES> coords = v.getCOORDINATES();\r
600       if (ds.isLocal()\r
601               || ((coords == null || coords.size() == 0)\r
602                       && filter1.getSelectedIndex() == 0\r
603                       && filter2.getSelectedIndex() == 0 && filter3\r
604                       .getSelectedIndex() == 0))\r
605       {\r
606         // THIS IS A FIX FOR LOCAL SOURCES WHICH DO NOT\r
607         // HAVE COORDINATE SYSTEMS, INFO WHICH AT PRESENT\r
608         // IS ADDED FROM THE REGISTRY\r
609         names.add(ds.getTitle());\r
610         selected.add(new Boolean(selectedSources.contains(ds.getTitle())));\r
611         continue;\r
612       }\r
613 \r
614       if (!selectedInList(dummyFeatureList, ds.getCapabilityList(v))\r
615               || !selectedInList(filter3.getSelectedValues(),\r
616                       ds.getLabelsFor(v)))\r
617       {\r
618         continue;\r
619       }\r
620 \r
621       for (int j = 0; j < coords.size(); j++)\r
622       {\r
623         if (selectedInList(filter1.getSelectedValues(), new String[]\r
624         { coords.get(j).getAuthority() })\r
625                 && selectedInList(filter2.getSelectedValues(), new String[]\r
626                 { coords.get(j).getSource() }))\r
627         {\r
628           names.add(ds.getTitle());\r
629           selected.add(new Boolean(selectedSources.contains(ds.getTitle())));\r
630           break;\r
631         }\r
632       }\r
633     }\r
634 \r
635     int dSize = names.size();\r
636     Object[][] data = new Object[dSize][2];\r
637     for (int d = 0; d < dSize; d++)\r
638     {\r
639       data[d][0] = names.get(d);\r
640       data[d][1] = selected.get(d);\r
641     }\r
642 \r
643     refreshTableData(data);\r
644   }\r
645 \r
646   private boolean selectedInList(Object[] selection, String[] items)\r
647   {\r
648     for (int i = 0; i < selection.length; i++)\r
649     {\r
650       if (selection[i].equals("Any"))\r
651       {\r
652         return true;\r
653       }\r
654       if (items == null || items.length == 0)\r
655       {\r
656         return false;\r
657       }\r
658       String sel = (items[0].startsWith("das1:") ? "das1:" : "")\r
659               + selection[i];\r
660       for (int j = 0; j < items.length; j++)\r
661       {\r
662         if (sel.equals(items[j]))\r
663         {\r
664           return true;\r
665         }\r
666       }\r
667     }\r
668 \r
669     return false;\r
670   }\r
671 \r
672   void setSelectedFromProperties()\r
673   {\r
674     String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
675             "uniprot");\r
676     StringTokenizer st = new StringTokenizer(active, "\t");\r
677     selectedSources = new Vector();\r
678     while (st.hasMoreTokens())\r
679     {\r
680       selectedSources.addElement(st.nextToken());\r
681     }\r
682   }\r
683 \r
684   public void reset_actionPerformed(ActionEvent e)\r
685   {\r
686     registryURL.setText(sourceRegistry.getDasRegistryURL());\r
687   }\r
688 \r
689   /**\r
690    * set the DAS source settings in the given jalview properties.\r
691    * \r
692    * @param properties\r
693    */\r
694   public void saveProperties(Properties properties)\r
695   {\r
696     if (registryURL.getText() == null || registryURL.getText().length() < 1)\r
697     {\r
698       properties.remove(jalview.bin.Cache.DAS_REGISTRY_URL);\r
699     }\r
700     else\r
701     {\r
702       properties.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,\r
703               registryURL.getText());\r
704     }\r
705 \r
706     StringBuffer sb = new StringBuffer();\r
707     for (int r = 0; r < table.getModel().getRowCount(); r++)\r
708     {\r
709       if (((Boolean) table.getValueAt(r, 1)).booleanValue())\r
710       {\r
711         sb.append(table.getValueAt(r, 0) + "\t");\r
712       }\r
713     }\r
714 \r
715     properties.setProperty(jalview.bin.Cache.DAS_ACTIVE_SOURCE,\r
716             sb.toString());\r
717 \r
718     String sourceprop = sourceRegistry.getLocalSourceString();\r
719     properties.setProperty(jalview.bin.Cache.DAS_LOCAL_SOURCE, sourceprop);\r
720   }\r
721 \r
722   class DASTableModel extends AbstractTableModel\r
723   {\r
724 \r
725     public DASTableModel(Object[][] data)\r
726     {\r
727       this.data = data;\r
728     }\r
729 \r
730     private String[] columnNames = new String[]\r
731     { "Nickname", "Use Source" };\r
732 \r
733     private Object[][] data;\r
734 \r
735     public int getColumnCount()\r
736     {\r
737       return columnNames.length;\r
738     }\r
739 \r
740     public int getRowCount()\r
741     {\r
742       return data.length;\r
743     }\r
744 \r
745     public String getColumnName(int col)\r
746     {\r
747       return columnNames[col];\r
748     }\r
749 \r
750     public Object getValueAt(int row, int col)\r
751     {\r
752       return data[row][col];\r
753     }\r
754 \r
755     /*\r
756      * JTable uses this method to determine the default renderer/ editor for\r
757      * each cell. If we didn't implement this method, then the last column would\r
758      * contain text ("true"/"false"), rather than a check box.\r
759      */\r
760     public Class getColumnClass(int c)\r
761     {\r
762       return getValueAt(0, c).getClass();\r
763     }\r
764 \r
765     /*\r
766      * Don't need to implement this method unless your table's editable.\r
767      */\r
768     public boolean isCellEditable(int row, int col)\r
769     {\r
770       // Note that the data/cell address is constant,\r
771       // no matter where the cell appears onscreen.\r
772       return col == 1;\r
773 \r
774     }\r
775 \r
776     /*\r
777      * Don't need to implement this method unless your table's data can change.\r
778      */\r
779     public void setValueAt(Object value, int row, int col)\r
780     {\r
781       data[row][col] = value;\r
782       fireTableCellUpdated(row, col);\r
783 \r
784       String name = getValueAt(row, 0).toString();\r
785       boolean selected = ((Boolean) value).booleanValue();\r
786 \r
787       if (selectedSources.contains(name) && !selected)\r
788       {\r
789         selectedSources.remove(name);\r
790       }\r
791 \r
792       if (!selectedSources.contains(name) && selected)\r
793       {\r
794         selectedSources.add(name);\r
795       }\r
796     }\r
797   }\r
798 \r
799   public void initDasSources()\r
800   {\r
801 \r
802     Thread thr = new Thread(new Runnable()\r
803     {\r
804       public void run()\r
805       {\r
806         // this actually initialises the das source list\r
807         paintComponent(null); // yuk\r
808       }\r
809     });\r
810     thr.start();\r
811     while (loadingDasSources || sourceRegistry == null)\r
812     {\r
813       try\r
814       {\r
815         Thread.sleep(10);\r
816       } catch (Exception e)\r
817       {\r
818       }\r
819       ;\r
820     }\r
821   }\r
822 \r
823   /**\r
824    * disable or enable the buttons on the source browser\r
825    * \r
826    * @param b\r
827    */\r
828   public void setGuiEnabled(boolean b)\r
829   {\r
830     refresh.setEnabled(b);\r
831     addLocal.setEnabled(b);\r
832   }\r
833 }\r