JAL-1668 added filtering and sorting capabilites
[jalview.git] / src / jalview / gui / StructureChooser.java
index 11fb943..9abf22f 100644 (file)
@@ -11,12 +11,19 @@ import jalview.ws.uimodel.PDBSearchRequest;
 import jalview.ws.uimodel.PDBSearchResponse;
 import jalview.ws.uimodel.PDBSearchResponse.PDBResponseSummary;
 
+import java.awt.Component;
+import java.awt.event.ItemEvent;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 
+import javax.swing.JCheckBox;
 import javax.swing.JOptionPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
 
 @SuppressWarnings("serial")
 public class StructureChooser extends GStructureChooser
@@ -28,105 +35,133 @@ public class StructureChooser extends GStructureChooser
 
   private SequenceI[] selectedSequences;
 
+  IProgressIndicator af;
+
+  Collection<PDBResponseSummary> discoveredStructuresSet = new HashSet<PDBResponseSummary>();
+
   public StructureChooser(AlignmentPanel ap, final SequenceI sequence)
   {
     this.ap = ap;
+    this.af = ap.alignFrame;
     this.selectedSequence = sequence;
-    selectedSequences = ((ap.av.getSelectionGroup() == null) ? new SequenceI[]
-    { sequence } : ap.av.getSequenceSelection());
-    fetchStructures();
-    populateFilterOptions();
-    updateCurrentView();
-  }
-
-  @Override
-  public void ok_ActionPerformed()
-  {
-    // TODO code to load selected structures to jmol or chimera
+    this.selectedSequences = ((ap.av.getSelectionGroup() == null) ? new SequenceI[]
+    { sequence }
+            : ap.av.getSequenceSelection());
+    init();
   }
 
-  protected void populateFilterOptions()
+  private void init()
   {
-    if (structuresWereFound)
+    Thread discPDBThread = new Thread(new Runnable()
     {
-      filterOptionsComboBox.addItem(new FilterOptions(
-              "- Filter Criteria -", "",
-              VIEWS_FILTER));
-      filterOptionsComboBox.addItem(new FilterOptions("All", "all",
-              VIEWS_FILTER));
-      filterOptionsComboBox.addItem(new FilterOptions("Best Coverage",
-              "coverage",
-              VIEWS_FILTER));
-      filterOptionsComboBox.addItem(new FilterOptions("Best Resolution",
-              PDBDocField.RESOLUTION.getCode(),
-              VIEWS_FILTER));
-      filterOptionsComboBox.addItem(new FilterOptions("Best Quality",
-              PDBDocField.OVERALL_QUALITY.getCode(),
-              VIEWS_FILTER));
-
-      // "number_of_polymers"), PROTEIN_CHAIN_COUNT(
-      // "Protein Chain Count", "number_of_protein_chains"),
-      // BOUND_MOLECULE_COUNT(
-      // "Bound Molecule Count", "number_of_bound_molecules"),
-      // POLYMER_RESIDUE_COUNT(
-      // "Polymer Residue Count", "number_of_polymer_residues"),
-      // UNIPROT_COVERAGE(
-    }
-    filterOptionsComboBox.addItem(new FilterOptions("Enter PDB Id", "-",
-            VIEWS_ENTER_ID));
-    filterOptionsComboBox.addItem(new FilterOptions("From File", "-",
-            VIEWS_FROM_FILE));
+      @Override
+      public void run()
+      {
+        long startTime = System.currentTimeMillis();
+        af.setProgressBar(
+                MessageManager.getString("status.fetching_db_refs"),
+                startTime);
+
+        fetchStructures();
+        populateFilterOptions();
+        af.setProgressBar(null, startTime);
+        mainFrame.setVisible(true);
+        updateCurrentView();
+      }
+    });
+    discPDBThread.start();
   }
 
   private void fetchStructures()
   {
     long startTime = System.currentTimeMillis();
-    // final SequenceI[] sequences = ((ap.av.getSelectionGroup() == null) ? new
-    // SequenceI[]
-    // { sequence }
-    // : ap.av.getSequenceSelection());
-
-    int foundStructures = 0;
     List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
-    wantedFields.add(PDBDocField.MOLECULE_TYPE);
+    // wantedFields.add(PDBDocField.MOLECULE_TYPE);
     wantedFields.add(PDBDocField.PDB_ID);
-    wantedFields.add(PDBDocField.GENUS);
-    wantedFields.add(PDBDocField.GENE_NAME);
+    // wantedFields.add(PDBDocField.GENUS);
+    // wantedFields.add(PDBDocField.GENE_NAME);
     wantedFields.add(PDBDocField.TITLE);
 
     PDBSearchRequest request = new PDBSearchRequest();
     request.setAllowEmptySeq(false);
     request.setResponseSize(500);
-    request.setSearchTarget("(text:");
+    request.setFieldToSearchBy("(text:");
     request.setWantedFields(wantedFields);
-    
-    Collection<PDBResponseSummary> searchSummaries = new HashSet<PDBResponseSummary>();
+
     for (SequenceI seq : selectedSequences)
     {
       request.setSearchTerm(buildQuery(seq) + ")");
+      request.setAssociatedSequence(seq.getName());
       PDBRestClient pdbRestCleint = new PDBRestClient();
-      PDBSearchResponse resultList = pdbRestCleint
-              .executeRequest(request);
+      PDBSearchResponse resultList = pdbRestCleint.executeRequest(request);
       if (resultList.getSearchSummary() != null
               && !resultList.getSearchSummary().isEmpty())
       {
-        searchSummaries.addAll(resultList.getSearchSummary());
+        discoveredStructuresSet.addAll(resultList.getSearchSummary());
       }
     }
 
-    foundStructures = searchSummaries.size();
-    if (searchSummaries != null)
+    int noOfStructuresFound = 0;
+    if (discoveredStructuresSet != null)
     {
       jListFoundStructures.setModel(PDBSearchResponse
-              .getListModel(searchSummaries));
+              .getListModel(discoveredStructuresSet));
+      summaryTable.setModel(PDBSearchResponse.getTableModel(request,
+              discoveredStructuresSet));
+      // resizeColumnWidth(summaryTable);
       structuresWereFound = true;
+      noOfStructuresFound = discoveredStructuresSet.size();
     }
     String totalTime = (System.currentTimeMillis() - startTime)
             + " milli secs";
-    mainFrame.setTitle("Structure Chooser - " + foundStructures
+    mainFrame.setTitle("Structure Chooser - " + noOfStructuresFound
             + " Found (" + totalTime + ")");
   }
 
+  public void resizeColumnWidth(JTable table)
+  {
+    // table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    final TableColumnModel columnModel = table.getColumnModel();
+    for (int column = 0; column < table.getColumnCount(); column++)
+    {
+      int width = 50; // Min width
+      for (int row = 0; row < table.getRowCount(); row++)
+      {
+        TableCellRenderer renderer = table.getCellRenderer(row, column);
+        Component comp = table.prepareRenderer(renderer, row, column);
+        width = Math.max(comp.getPreferredSize().width, width);
+      }
+      columnModel.getColumn(column).setPreferredWidth(width);
+    }
+  }
+
+  protected void populateFilterOptions()
+  {
+    if (structuresWereFound)
+    {
+      filterOptionsComboBox.addItem(new FilterOptions("Best Quality",
+              PDBDocField.OVERALL_QUALITY.getCode(), VIEWS_FILTER));
+      filterOptionsComboBox.addItem(new FilterOptions(
+              "Best UniProt Coverage", PDBDocField.UNIPROT_COVERAGE
+                      .getCode(), VIEWS_FILTER));
+      filterOptionsComboBox.addItem(new FilterOptions("Highest Resolution",
+              PDBDocField.RESOLUTION.getCode(), VIEWS_FILTER));
+      filterOptionsComboBox.addItem(new FilterOptions(
+              "Highest Protein Chain", PDBDocField.PROTEIN_CHAIN_COUNT
+                      .getCode(), VIEWS_FILTER));
+      filterOptionsComboBox.addItem(new FilterOptions(
+              "Highest Bound Molecules", PDBDocField.BOUND_MOLECULE_COUNT
+                      .getCode(), VIEWS_FILTER));
+      filterOptionsComboBox.addItem(new FilterOptions(
+              "Highest Polymer Residues", PDBDocField.POLYMER_RESIDUE_COUNT
+                      .getCode(), VIEWS_FILTER));
+    }
+    filterOptionsComboBox.addItem(new FilterOptions("Enter PDB Id", "-",
+            VIEWS_ENTER_ID));
+    filterOptionsComboBox.addItem(new FilterOptions("From File", "-",
+            VIEWS_FROM_FILE));
+  }
+
   private String buildQuery(SequenceI seq)
   {
     String query = seq.getName();
@@ -150,66 +185,131 @@ public class StructureChooser extends GStructureChooser
     return query;
   }
 
-  @Override
-  protected void stateChanged()
-  {
-    updateCurrentView();
-  }
-
-  int debounceCount = 0;
   protected void updateCurrentView()
   {
     FilterOptions currentOption = ((FilterOptions) filterOptionsComboBox
             .getSelectedItem());
     switchableViewsLayout.show(switchableViewsPanel,
             currentOption.getView());
-    ++debounceCount;
-    if (currentOption.getView() == VIEWS_FILTER && debounceCount % 2 == 0)
+    invertFilter.setEnabled(false);
+    if (currentOption.getView() == VIEWS_FILTER)
     {
+      invertFilter.setEnabled(true);
       filterResultSet(currentOption.getValue());
     }
   }
 
-  public void filterResultSet(String filterTarget)
+  public void filterResultSet(final String fieldToFilterBy)
   {
-    System.out.println("-----------------> Filter by : " + filterTarget);
+    Thread filterThread = new Thread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        try
+        {
+        loadingImageLabel.setVisible(true);
+        List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
+        // wantedFields.add(PDBDocField.MOLECULE_TYPE);
+        wantedFields.add(PDBDocField.PDB_ID);
+        // wantedFields.add(PDBDocField.GENUS);
+        // wantedFields.add(PDBDocField.GENE_NAME);
+        wantedFields.add(PDBDocField.TITLE);
+
+        PDBSearchRequest request = new PDBSearchRequest();
+        request.setAllowEmptySeq(false);
+        request.setResponseSize(1);
+        request.setFieldToSearchBy("(text:");
+        request.setFieldToSortBy(fieldToFilterBy,
+                !invertFilter.isSelected());
+
+        request.setWantedFields(wantedFields);
+
+        Collection<PDBResponseSummary> filteredResponse = new HashSet<PDBResponseSummary>();
+        for (SequenceI seq : selectedSequences)
+        {
+          request.setSearchTerm(buildQuery(seq) + ")");
+          request.setAssociatedSequence(seq.getName());
+          PDBRestClient pdbRestCleint = new PDBRestClient();
+          PDBSearchResponse resultList = pdbRestCleint
+                  .executeRequest(request);
+          if (resultList.getSearchSummary() != null
+                  && !resultList.getSearchSummary().isEmpty())
+          {
+            filteredResponse.addAll(resultList.getSearchSummary());
+          }
+        }
 
-    List<PDBDocField> wantedFields = new ArrayList<PDBDocField>();
-    wantedFields.add(PDBDocField.MOLECULE_TYPE);
-    wantedFields.add(PDBDocField.PDB_ID);
-    wantedFields.add(PDBDocField.GENUS);
-    wantedFields.add(PDBDocField.GENE_NAME);
-    wantedFields.add(PDBDocField.TITLE);
 
-    PDBSearchRequest request = new PDBSearchRequest();
-    request.setAllowEmptySeq(false);
-    request.setResponseSize(1);
-    request.setSearchTarget("(text:");
-    request.setSortTarget(filterTarget, true);
+        if (filteredResponse != null)
+        {
+            //
+            // for (PDBResponseSummary s : filteredResponse)
+            // {
+            // System.out.println("-----------> " + s.getPdbId());
+            // }
+
+          int filterResponseCount = filteredResponse.size();
+          List<PDBResponseSummary> list = new ArrayList<PDBResponseSummary>(
+                  discoveredStructuresSet);
+          list.removeAll(filteredResponse);
+
+          Collection<PDBResponseSummary> newSet = new ArrayList<PDBResponseSummary>();
+          newSet.addAll(filteredResponse);
+          newSet.addAll(list);
+
+          jListFoundStructures.setModel(PDBSearchResponse
+                  .getListModel(newSet));
+          summaryTable.setModel(PDBSearchResponse.getTableModel(request,
+                  newSet));
+          // resizeColumnWidth(summaryTable);
+          list = null;
+          newSet = null;
+
+          int[] filterIndice = new int[filterResponseCount];
+          ListSelectionModel model = summaryTable.getSelectionModel();
+          model.clearSelection();
+          // int x = 0;
+          for (int x = 0; x < filterResponseCount; x++)
+          {
+            filterIndice[x] = x;
+            model.addSelectionInterval(x, x);
+          }
+          jListFoundStructures.setSelectedIndices(filterIndice);
+        }
 
-    request.setWantedFields(wantedFields);
+        loadingImageLabel.setVisible(false);
+        } catch (Exception e)
+        {
+          e.printStackTrace();
+        }
+      }
+    });
+    filterThread.start();
 
-    Collection<PDBResponseSummary> searchSummaries = new HashSet<PDBResponseSummary>();
-    for (SequenceI seq : selectedSequences)
+  }
+
+  @Override
+  protected void stateChanged(ItemEvent e)
+  {
+    if (e.getSource() instanceof JCheckBox)
     {
-      request.setSearchTerm(buildQuery(seq) + ")");
-      PDBRestClient pdbRestCleint = new PDBRestClient();
-      PDBSearchResponse resultList = pdbRestCleint.executeRequest(request);
-      if (resultList.getSearchSummary() != null
-              && !resultList.getSearchSummary().isEmpty())
+      updateCurrentView();
+    }
+    else
+    {
+      if (e.getStateChange() == ItemEvent.SELECTED)
       {
-        searchSummaries.addAll(resultList.getSearchSummary());
-
+        updateCurrentView();
       }
     }
 
-    for (PDBResponseSummary summary : searchSummaries)
-    {
-      jListFoundStructures.setSelectedValue(summary, true);
-      // jListFoundStructures.
-      break;
-    }
-    System.out.println("Found item count : " + searchSummaries.size());
+  }
+
+  @Override
+  public void ok_ActionPerformed()
+  {
+    // TODO code to load selected structures to jmol or chimera
   }
 
   public void pdbFromFile_actionPerformed()
@@ -237,7 +337,6 @@ public class StructureChooser extends GStructureChooser
 
   }
 
-
   // rpdbview.addActionListener(new ActionListener()
   // {
   //
@@ -263,16 +362,4 @@ public class StructureChooser extends GStructureChooser
     }
   }
 
-  // public static void main(String[] args)
-  // {
-  // SwingUtilities.invokeLater(new Runnable()
-  // {
-  // public void run()
-  // {
-  // new StructureChooser(null, null);
-  // }
-  // });
-  // }
-
-
 }