JAL-4048 fix disappearing sequence IDs, and non-positional feature descriptions
[jalview.git] / src / jalview / viewmodel / seqfeatures / IdColumns.java
1 package jalview.viewmodel.seqfeatures;
2
3 import java.awt.Color;
4 import java.util.ArrayList;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Vector;
8
9 import jalview.api.DBRefEntryI;
10 import jalview.datamodel.AlignmentI;
11 import jalview.datamodel.SequenceFeature;
12 import jalview.datamodel.SequenceI;
13 import jalview.datamodel.features.SequenceFeaturesI;
14
15 public class IdColumns
16 {
17
18   AlignmentI alignment = null;
19
20   public IdColumns(AlignmentI al)
21   {
22     alignment = al;
23     columns.put(STRUCTURES_NUM.getLabel(), STRUCTURES_NUM);
24     updateTypeList();
25   }
26
27   public final static IdColumn STRUCTURES_NUM;
28   static
29   {
30     STRUCTURES_NUM = new IdColumn("3D Structures",
31             "Number of associated structure files", false);
32   }
33
34   LinkedHashMap<String, IdColumn> columns = new LinkedHashMap<String, IdColumn>();
35
36   /**
37    * register a feature on the columnset
38    * 
39    * @param sf
40    * @return true if feature was not seen before
41    */
42   boolean updateListForFeature(SequenceFeature sf)
43   {
44     String colname = sf.getType();
45     if (columns.get(colname) != null)
46     {
47       return false;
48     }
49
50     IdColumn col = new IdColumn(colname,
51             "Nonpositional feature: " + colname, false);
52     col.featureTypeName = sf.getType();
53     // col.featureGroupName = sf.getFeatureGroup();
54     columns.put(colname, col);
55     return true;
56   }
57
58   boolean updateListForDbxref(DBRefEntryI dbref)
59   {
60     String colname = dbref.getSource();
61     if (columns.get(colname) != null)
62     {
63       return false;
64     }
65
66     IdColumn col = new IdColumn(colname,
67             "Database CrossReference: " + colname, false);
68     col.DbRefName = colname;
69     // col.featureGroupName = sf.getFeatureGroup();
70     columns.put(colname, col);
71     return true;
72   }
73
74   public void updateTypeList()
75   {
76     for (SequenceI sq : alignment.getSequences())
77     {
78       SequenceI seq = sq;
79       while (seq.getDatasetSequence() != null)
80       {
81         seq = seq.getDatasetSequence();
82       }
83
84       SequenceFeaturesI sqf = seq.getFeatures();
85       List<SequenceFeature> nonpos = sqf.getNonPositionalFeatures();
86       if (nonpos != null)
87       {
88         for (SequenceFeature sf : nonpos)
89         {
90           updateListForFeature(sf);
91         }
92       }
93       for (DBRefEntryI dbr : seq.getDBRefs())
94       {
95         updateListForDbxref(dbr);
96       }
97     }
98   }
99
100   public void toggleVisible(String column)
101   {
102     IdColumn col = columns.get(column);
103     if (col != null)
104     {
105       col.visible = !col.visible;
106     }
107   }
108
109   public List<IdColumn> getVisible()
110   {
111     // probably want to cache this
112     ArrayList<IdColumn> vis = new ArrayList();
113     for (IdColumn col : columns.values())
114     {
115       if (col.visible)
116       {
117         vis.add(col);
118       }
119     }
120     return vis;
121   }
122
123   public final class ColumnCell
124   {
125     public final String label;
126
127     public final Color bg;
128
129     public final Color fg;
130
131     public ColumnCell(final String label, final Color bg, final Color fg)
132     {
133       this.label = label;
134       this.bg = bg;
135       this.fg = fg;
136     }
137   }
138
139   /**
140    * render the column value for this sequence
141    * 
142    * @param seq
143    * @param col
144    * @return
145    */
146   public ColumnCell getCellFor(SequenceI seq, IdColumn col)
147   {
148     ColumnCell cell = null;
149     if (col != null)
150     {
151       SequenceI dseq = seq;
152       while (dseq.getDatasetSequence() != null)
153       {
154         dseq = dseq.getDatasetSequence();
155       }
156       if (col == STRUCTURES_NUM)
157       {
158         Vector pdbE = dseq.getAllPDBEntries();
159         if (pdbE == null)
160         {
161           return null;
162         }
163         return new ColumnCell("" + pdbE.size(), Color.red, Color.white);
164       }
165       if (col.featureTypeName != null)
166       {
167         List<SequenceFeature> np = dseq.getFeatures()
168                 .getNonPositionalFeatures(col.featureTypeName);
169         if (np != null)
170         {
171           for (SequenceFeature npfeat : np)
172           {
173             // nb deal with multiplicities!
174             if (col.featureGroupName != null && npfeat.featureGroup != null
175                     && npfeat.featureGroup.equals(col.featureGroupName))
176             {
177               Color fg = Color.black;
178               Color bg = Color.white;
179
180               return new ColumnCell(npfeat.description, fg, bg);
181             }
182           }
183         }
184       }
185       if (col.DbRefName != null)
186       {
187         for (DBRefEntryI dbr : dseq.getDBRefs())
188         {
189           if (dbr.getSource().equals(col.DbRefName))
190           {
191             return new ColumnCell(dbr.getAccessionId(), Color.black,
192                     Color.white);
193           }
194         }
195       }
196     }
197     // no value for this sequence in given column
198     return null;
199   }
200
201   public IdColumn[] getIdColumns()
202   {
203     return columns.values().toArray(new IdColumn[0]);
204   }
205 }