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