Merge branch 'develop' of https://source.jalview.org/git/jalview.git into develop
[jalview.git] / src / jalview / jbgui / PDBDocFieldPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.jbgui;
22
23 import jalview.ws.dbsources.PDBRestClient.PDBDocField;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.LinkedHashSet;
29 import java.util.List;
30
31 import javax.swing.JScrollPane;
32 import javax.swing.JTable;
33 import javax.swing.RowSorter;
34 import javax.swing.SortOrder;
35 import javax.swing.table.AbstractTableModel;
36 import javax.swing.table.TableModel;
37 import javax.swing.table.TableRowSorter;
38
39 @SuppressWarnings("serial")
40 public class PDBDocFieldPreferences extends JScrollPane
41 {
42   protected JTable tbl_pdbDocFieldConfig = new JTable();
43
44   protected JScrollPane scrl_pdbDocFieldConfig = new JScrollPane(
45           tbl_pdbDocFieldConfig);
46
47   private HashMap<String, PDBDocField> map = new HashMap<String, PDBDocField>();
48
49   private static Collection<PDBDocField> searchSummaryFields = new LinkedHashSet<PDBDocField>();
50
51   private static Collection<PDBDocField> structureSummaryFields = new LinkedHashSet<PDBDocField>();
52
53   public enum PreferenceSource
54   {
55     SEARCH_SUMMARY, STRUCTURE_CHOOSER, PREFERENCES;
56   }
57
58   private PreferenceSource currentSource;
59
60   static
61   {
62     searchSummaryFields.add(PDBDocField.PDB_ID);
63     searchSummaryFields.add(PDBDocField.TITLE);
64
65     structureSummaryFields.add(PDBDocField.PDB_ID);
66     structureSummaryFields.add(PDBDocField.TITLE);
67   }
68
69   public PDBDocFieldPreferences(PreferenceSource source)
70   {
71     tbl_pdbDocFieldConfig.setAutoCreateRowSorter(true);
72
73
74
75     this.getViewport().add(tbl_pdbDocFieldConfig);
76     this.currentSource = source;
77
78     String[] columnNames = null;
79     switch (source)
80     {
81     case SEARCH_SUMMARY:
82       columnNames = new String[] { "", "Display", "Group" };
83       break;
84     case STRUCTURE_CHOOSER:
85       columnNames = new String[] { " ", "Display", "Group" };
86       break;
87     case PREFERENCES:
88       columnNames = new String[] { "PDB Field", "Show in search summary",
89           "Show in structure summary" };
90       break;
91     default:
92       break;
93     }
94
95     Object[][] data = new Object[PDBDocField.values().length - 1][3];
96     int x = 0;
97     for (PDBDocField field : PDBDocField.values())
98     {
99       if (field.getName().equalsIgnoreCase("all"))
100       {
101         continue;
102       }
103
104       switch (source)
105       {
106       case SEARCH_SUMMARY:
107         data[x++] = new Object[] { searchSummaryFields.contains(field),
108             field.getName(), field.getGroup() };
109         break;
110       case STRUCTURE_CHOOSER:
111         data[x++] = new Object[] { structureSummaryFields.contains(field),
112             field.getName(), field.getGroup() };
113         break;
114       case PREFERENCES:
115         data[x++] = new Object[] { field.getName(),
116             searchSummaryFields.contains(field),
117             structureSummaryFields.contains(field) };
118         break;
119       default:
120         break;
121       }
122       map.put(field.getName(), field);
123     }
124
125     PDBFieldTableModel model = new PDBFieldTableModel(columnNames, data);
126     tbl_pdbDocFieldConfig.setModel(model);
127
128     // DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
129     // rightRenderer.setHorizontalAlignment(SwingConstants.LEFT);
130     // tbl_pdbDocFieldConfig.getColumn("Show in structure summary")
131     // .setCellRenderer(rightRenderer);
132     switch (source)
133     {
134     case SEARCH_SUMMARY:
135     case STRUCTURE_CHOOSER:
136       tbl_pdbDocFieldConfig.getColumnModel().getColumn(0)
137               .setPreferredWidth(5);
138       tbl_pdbDocFieldConfig.getColumnModel().getColumn(1)
139               .setPreferredWidth(195);
140       tbl_pdbDocFieldConfig.getColumnModel().getColumn(2)
141               .setPreferredWidth(200);
142
143       TableRowSorter<TableModel> sorter = new TableRowSorter<>(
144               tbl_pdbDocFieldConfig.getModel());
145       tbl_pdbDocFieldConfig.setRowSorter(sorter);
146       List<RowSorter.SortKey> sortKeys = new ArrayList<>();
147       int columnIndexToSort = 2;
148       sortKeys.add(new RowSorter.SortKey(columnIndexToSort,
149               SortOrder.ASCENDING));
150       sorter.setSortKeys(sortKeys);
151       sorter.sort();
152       break;
153     case PREFERENCES:
154     default:
155       break;
156     }
157
158
159   }
160
161   public static Collection<PDBDocField> getSearchSummaryFields()
162   {
163     return searchSummaryFields;
164   }
165
166   public static void setSearchSummaryFields(
167           Collection<PDBDocField> searchSummaryFields)
168   {
169     PDBDocFieldPreferences.searchSummaryFields = searchSummaryFields;
170   }
171
172   public static Collection<PDBDocField> getStructureSummaryFields()
173   {
174     return structureSummaryFields;
175   }
176
177   public static void setStructureSummaryFields(
178           Collection<PDBDocField> structureSummaryFields)
179   {
180     PDBDocFieldPreferences.structureSummaryFields = structureSummaryFields;
181   }
182
183   class PDBFieldTableModel extends AbstractTableModel
184   {
185
186     public PDBFieldTableModel(String[] columnNames, Object[][] data)
187     {
188       this.data = data;
189       this.columnNames = columnNames;
190     }
191
192     private Object[][] data;
193
194     private String[] columnNames;
195
196     @Override
197     public int getColumnCount()
198     {
199       return columnNames.length;
200     }
201
202     @Override
203     public int getRowCount()
204     {
205       return data.length;
206     }
207
208     @Override
209     public String getColumnName(int col)
210     {
211       return columnNames[col];
212     }
213
214     @Override
215     public Object getValueAt(int row, int col)
216     {
217       return data[row][col];
218     }
219
220     /*
221      * JTable uses this method to determine the default renderer/ editor for
222      * each cell. If we didn't implement this method, then the last column would
223      * contain text ("true"/"false"), rather than a check box.
224      */
225     @Override
226     public Class getColumnClass(int c)
227     {
228       return getValueAt(0, c).getClass();
229     }
230
231     /*
232      * Don't need to implement this method unless your table's editable.
233      */
234     @Override
235     public boolean isCellEditable(int row, int col)
236     {
237       // Note that the data/cell address is constant,
238       // no matter where the cell appears onscreen.
239       // !isPDBID(row, col) ensures the PDB_Id cell is never editable as it
240       // serves as a unique id for each row.
241       // return (col == 1 || col == 2) && !isPDBID(row, col);
242       switch (currentSource)
243       {
244       case SEARCH_SUMMARY:
245       case STRUCTURE_CHOOSER:
246         return (col == 0) && !isPDBID(row, 1);
247       case PREFERENCES:
248         return (col == 1 || col == 2) && !isPDBID(row, 0);
249       default:
250         return false;
251       }
252
253     }
254
255     /**
256      * Determines whether the data in a given cell is a PDB ID.
257      * 
258      * @param row
259      * @param col
260      * @return
261      */
262
263     public boolean isPDBID(int row, int col)
264     {
265       boolean matched = false;
266       String name = getValueAt(row, col).toString();
267       PDBDocField pdbField = map.get(name);
268       if (pdbField == PDBDocField.PDB_ID)
269       {
270         matched = true;
271       }
272       return matched;
273     }
274
275     /*
276      * Don't need to implement this method unless your table's data can change.
277      */
278     @Override
279     public void setValueAt(Object value, int row, int col)
280     {
281       data[row][col] = value;
282       fireTableCellUpdated(row, col);
283
284       String name = null;
285       switch (currentSource)
286       {
287       case SEARCH_SUMMARY:
288       case STRUCTURE_CHOOSER:
289         name = getValueAt(row, 1).toString();
290         break;
291       case PREFERENCES:
292         name = getValueAt(row, 0).toString();
293         break;
294       default:
295         break;
296       }
297       boolean selected = ((Boolean) value).booleanValue();
298
299       PDBDocField pdbField = map.get(name);
300
301       if (currentSource == PreferenceSource.SEARCH_SUMMARY)
302       {
303         updatePrefs(searchSummaryFields, pdbField, selected);
304       }
305       else if (currentSource == PreferenceSource.STRUCTURE_CHOOSER)
306       {
307         updatePrefs(structureSummaryFields, pdbField, selected);
308       }
309       else if (currentSource == PreferenceSource.PREFERENCES)
310       {
311         if (col == 1)
312         {
313           updatePrefs(searchSummaryFields, pdbField, selected);
314         }
315         else if (col == 2)
316         {
317           updatePrefs(structureSummaryFields, pdbField, selected);
318         }
319       }
320     }
321
322     private void updatePrefs(Collection<PDBDocField> prefConfig,
323             PDBDocField pdbField, boolean selected)
324     {
325       if (prefConfig.contains(pdbField) && !selected)
326       {
327         prefConfig.remove(pdbField);
328       }
329
330       if (!prefConfig.contains(pdbField) && selected)
331       {
332         prefConfig.add(pdbField);
333       }
334     }
335
336   }
337 }