JAL-1445 ported routine for selecting containing/non-containing columns from groovy...
[jalview.git] / src / jalview / controller / AlignViewController.java
1 package jalview.controller;
2
3 import java.awt.Color;
4 import java.util.BitSet;
5 import java.util.List;
6
7 import jalview.api.AlignViewControllerGuiI;
8 import jalview.api.AlignViewControllerI;
9 import jalview.api.AlignViewportI;
10 import jalview.api.AlignmentViewPanel;
11 import jalview.datamodel.ColumnSelection;
12 import jalview.datamodel.SequenceFeature;
13 import jalview.datamodel.SequenceGroup;
14 import jalview.datamodel.SequenceI;
15
16 public class AlignViewController implements AlignViewControllerI
17 {
18   AlignViewportI viewport=null;
19   AlignmentViewPanel alignPanel=null;
20   /**
21    * the GUI container that is handling interactions with the user
22    */
23   private AlignViewControllerGuiI avcg;
24   @Override
25   protected void finalize() throws Throwable {
26     viewport = null;
27     alignPanel = null;
28     avcg = null;
29   };
30   
31   public AlignViewController(AlignViewControllerGuiI alignFrame, AlignViewportI viewport,
32           AlignmentViewPanel alignPanel)
33   {
34     this.avcg = alignFrame;
35     this.viewport=viewport;
36     this.alignPanel = alignPanel;
37   }
38   @Override
39   public void setViewportAndAlignmentPanel(AlignViewportI viewport,AlignmentViewPanel alignPanel)
40   {
41     this.alignPanel = alignPanel;
42     this.viewport = viewport;
43     
44   }
45   @Override
46   public boolean makeGroupsFromSelection()
47   {
48
49     if (viewport.getSelectionGroup() != null)
50     {
51       SequenceGroup[] gps = jalview.analysis.Grouping.makeGroupsFrom(
52               viewport.getSequenceSelection(),
53               viewport.getAlignmentView(true).getSequenceStrings(
54                       viewport.getGapCharacter()), viewport.getAlignment()
55                       .getGroups());
56       viewport.getAlignment().deleteAllGroups();
57       viewport.clearSequenceColours();
58       viewport.setSelectionGroup(null);
59       // set view properties for each group
60       for (int g = 0; g < gps.length; g++)
61       {
62         // gps[g].setShowunconserved(viewport.getShowUnconserved());
63         gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
64         viewport.getAlignment().addGroup(gps[g]);
65         Color col = new Color((int) (Math.random() * 255),
66                 (int) (Math.random() * 255), (int) (Math.random() * 255));
67         col = col.brighter();
68         for (SequenceI sq : gps[g].getSequences(null))
69           viewport.setSequenceColour(sq, col);
70       }
71       return true;
72     }
73     return false;
74 }
75   @Override
76   public boolean createGroup()
77   {
78
79     SequenceGroup sg = viewport.getSelectionGroup();
80     if (sg!=null)
81     {
82         viewport.getAlignment().addGroup(sg);
83         return true;
84       } 
85     return false;
86   }
87   @Override
88   public boolean unGroup()
89   {
90     SequenceGroup sg = viewport.getSelectionGroup();
91     if (sg!=null)
92     {
93         viewport.getAlignment().deleteGroup(sg);
94         return true;
95     }
96     return false;
97   }
98   @Override
99   public boolean deleteGroups()
100   {
101     if (viewport.getAlignment().getGroups()!=null && viewport.getAlignment().getGroups().size()>0)
102     {
103     viewport.getAlignment().deleteAllGroups();
104     viewport.clearSequenceColours();
105     viewport.setSelectionGroup(null);
106     return true;
107     }
108     return false;
109   }
110    
111   @Override
112   public boolean markColumnsContainingFeatures(boolean invert,
113           String featureType)
114   {
115     // JBPNote this routine could also mark rows, not just columns.
116     // need a decent query structure to allow all types of feature searches
117     BitSet bs = new BitSet();
118     List<SequenceI> seqs = viewport.getAlignment().getSequences();
119     int alw = viewport.getAlignment().getWidth();
120     int nseq = 0;
121     for (SequenceI sq : seqs)
122     {
123       int tfeat = 0;
124       if (sq != null)
125       {
126         SequenceI dsq = sq.getDatasetSequence();
127         while (dsq.getDatasetSequence() != null)
128         {
129           dsq = dsq.getDatasetSequence();
130         }
131         ;
132         SequenceFeature[] sf = dsq.getSequenceFeatures();
133         if (sf != null)
134         {
135           for (SequenceFeature sfpos : sf)
136           {
137             // future functionalty - featureType == null means mark columns
138             // containing all displayed features
139             if (sfpos != null && (featureType.equals(sfpos.getType())))
140             {
141               tfeat++;
142               // optimisation - could consider 'spos,apos' like cursor argument
143               // - findIndex wastes time by starting from first character and
144               // counting
145
146               int i = sq.findIndex(sfpos.getBegin());
147               int ist = sq.findIndex(sq.getStart());
148               if (i < ist)
149               {
150                 i = ist;
151               }
152               int j = sq.findIndex(sfpos.getEnd());
153               if (j > alw)
154               {
155                 j = alw;
156               }
157               for (; i <= j; i++)
158               {
159                 bs.set(i - 1);
160               }
161             }
162           }
163         }
164
165         if (tfeat > 0)
166         {
167           nseq++;
168         }
169       }
170     }
171     if (bs.cardinality() > 0 || invert)
172     {
173       ColumnSelection cs = viewport.getColumnSelection();
174       if (cs == null)
175       {
176         cs = new ColumnSelection();
177       }
178       if (invert)
179       {
180         for (int i = bs.nextClearBit(0), ibs = bs.nextSetBit(0); i >= 0
181                 && i < alw;)
182         {
183           if (ibs < 0 || i < ibs)
184           {
185             cs.addElement(i++);
186           }
187           else
188           {
189             i = bs.nextClearBit(ibs);
190             ibs = bs.nextSetBit(i);
191           }
192         }
193       }
194       else
195       {
196         for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
197         {
198           cs.addElement(i);
199         }
200       }
201       viewport.setColumnSelection(cs);
202       alignPanel.paintAlignment(true);
203       avcg.setStatus("Marked "
204               + (invert ? alw - bs.cardinality() : bs.cardinality())
205               + " columns containing features of type " + featureType
206               + " across " + nseq);
207       return true;
208     }
209     else
210     {
211       avcg.setStatus("No features of type " + featureType + " found.");
212       return false;
213     }
214   }
215 }