JAL-2488 remove finalize methods
[jalview.git] / src / jalview / appletgui / AlignViewport.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.appletgui;
22
23 import jalview.analysis.TreeModel;
24 import jalview.api.AlignViewportI;
25 import jalview.api.FeatureSettingsModelI;
26 import jalview.bin.JalviewLite;
27 import jalview.commands.CommandI;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.Annotation;
30 import jalview.datamodel.ColumnSelection;
31 import jalview.datamodel.HiddenColumns;
32 import jalview.datamodel.SearchResults;
33 import jalview.datamodel.SearchResultsI;
34 import jalview.datamodel.Sequence;
35 import jalview.datamodel.SequenceGroup;
36 import jalview.datamodel.SequenceI;
37 import jalview.renderer.ResidueShader;
38 import jalview.schemes.ColourSchemeProperty;
39 import jalview.schemes.UserColourScheme;
40 import jalview.structure.SelectionSource;
41 import jalview.structure.StructureSelectionManager;
42 import jalview.structure.VamsasSource;
43 import jalview.viewmodel.AlignmentViewport;
44
45 import java.awt.Font;
46 import java.awt.FontMetrics;
47
48 public class AlignViewport extends AlignmentViewport
49         implements SelectionSource
50 {
51   boolean cursorMode = false;
52
53   Font font = new Font("SansSerif", Font.PLAIN, 10);
54
55   boolean validCharWidth = true;
56
57   TreeModel currentTree = null;
58
59   public jalview.bin.JalviewLite applet;
60
61   boolean MAC = false;
62
63   private AnnotationColumnChooser annotationColumnSelectionState;
64
65   public AlignViewport(AlignmentI al, JalviewLite applet)
66   {
67     super(al);
68     calculator = new jalview.workers.AlignCalcManager();
69     this.applet = applet;
70
71     // we always pad gaps
72     this.setPadGaps(true);
73
74     if (applet != null)
75     {
76       // get the width and height scaling factors if they were specified
77       String param = applet.getParameter("widthScale");
78       if (param != null)
79       {
80         try
81         {
82           widthScale = new Float(param).floatValue();
83         } catch (Exception e)
84         {
85         }
86         if (widthScale <= 1.0)
87         {
88           System.err.println(
89                   "Invalid alignment character width scaling factor ("
90                           + widthScale + "). Ignoring.");
91           widthScale = 1;
92         }
93         if (JalviewLite.debug)
94         {
95           System.err.println(
96                   "Alignment character width scaling factor is now "
97                           + widthScale);
98         }
99       }
100       param = applet.getParameter("heightScale");
101       if (param != null)
102       {
103         try
104         {
105           heightScale = new Float(param).floatValue();
106         } catch (Exception e)
107         {
108         }
109         if (heightScale <= 1.0)
110         {
111           System.err.println(
112                   "Invalid alignment character height scaling factor ("
113                           + heightScale + "). Ignoring.");
114           heightScale = 1;
115         }
116         if (JalviewLite.debug)
117         {
118           System.err.println(
119                   "Alignment character height scaling factor is now "
120                           + heightScale);
121         }
122       }
123     }
124     setFont(font, true);
125
126     MAC = new jalview.util.Platform().isAMac();
127
128     if (applet != null)
129     {
130       setShowJVSuffix(
131               applet.getDefaultParameter("showFullId", getShowJVSuffix()));
132
133       setShowAnnotation(applet.getDefaultParameter("showAnnotation",
134               isShowAnnotation()));
135
136       showConservation = applet.getDefaultParameter("showConservation",
137               showConservation);
138
139       showQuality = applet.getDefaultParameter("showQuality", showQuality);
140
141       showConsensus = applet.getDefaultParameter("showConsensus",
142               showConsensus);
143
144       showOccupancy = applet.getDefaultParameter("showOccupancy",
145               showOccupancy);
146
147       setShowUnconserved(applet.getDefaultParameter("showUnconserved",
148               getShowUnconserved()));
149
150       setScaleProteinAsCdna(applet.getDefaultParameter("scaleProteinAsCdna",
151               isScaleProteinAsCdna()));
152
153       String param = applet.getParameter("upperCase");
154       if (param != null)
155       {
156         if (param.equalsIgnoreCase("bold"))
157         {
158           setUpperCasebold(true);
159         }
160       }
161       sortByTree = applet.getDefaultParameter("sortByTree", sortByTree);
162
163       setFollowHighlight(applet.getDefaultParameter("automaticScrolling",
164               isFollowHighlight()));
165       followSelection = isFollowHighlight();
166
167       showSequenceLogo = applet.getDefaultParameter("showSequenceLogo",
168               showSequenceLogo);
169
170       normaliseSequenceLogo = applet.getDefaultParameter(
171               "normaliseSequenceLogo", applet.getDefaultParameter(
172                       "normaliseLogo", normaliseSequenceLogo));
173
174       showGroupConsensus = applet.getDefaultParameter("showGroupConsensus",
175               showGroupConsensus);
176
177       showGroupConservation = applet.getDefaultParameter(
178               "showGroupConservation", showGroupConservation);
179
180       showConsensusHistogram = applet.getDefaultParameter(
181               "showConsensusHistogram", showConsensusHistogram);
182
183     }
184
185     if (applet != null)
186     {
187       String colour = al.isNucleotide()
188               ? applet.getParameter("defaultColourNuc")
189               : applet.getParameter("defaultColourProt");
190       if (colour == null)
191       {
192         colour = applet.getParameter("defaultColour");
193       }
194       if (colour == null)
195       {
196         colour = applet.getParameter("userDefinedColour");
197         if (colour != null)
198         {
199           colour = "User Defined";
200         }
201       }
202
203       if (colour != null)
204       {
205         residueShading = new ResidueShader(
206                 ColourSchemeProperty.getColourScheme(alignment, colour));
207         if (residueShading != null)
208         {
209           residueShading.setConsensus(hconsensus);
210         }
211       }
212
213       if (applet.getParameter("userDefinedColour") != null)
214       {
215         residueShading = new ResidueShader(new UserColourScheme(
216                 applet.getParameter("userDefinedColour")));
217       }
218     }
219     initAutoAnnotation();
220
221   }
222
223   java.awt.Frame nullFrame;
224
225   protected FeatureSettings featureSettings = null;
226
227   private float heightScale = 1, widthScale = 1;
228
229   /**
230    * {@inheritDoc}
231    */
232   @Override
233   public void setFont(Font f, boolean setGrid)
234   {
235     font = f;
236     if (nullFrame == null)
237     {
238       nullFrame = new java.awt.Frame();
239       nullFrame.addNotify();
240     }
241
242     if (setGrid)
243     {
244       FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
245       setCharHeight((int) (heightScale * fm.getHeight()));
246       setCharWidth((int) (widthScale * fm.charWidth('M')));
247     }
248
249     if (isUpperCasebold())
250     {
251       Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());
252       FontMetrics fm = nullFrame.getGraphics().getFontMetrics(f2);
253       setCharWidth(
254               (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10)));
255     }
256   }
257
258   public Font getFont()
259   {
260     return font;
261   }
262
263   public void resetSeqLimits(int height)
264   {
265     ranges.setEndSeq(height / getCharHeight());
266   }
267
268   public void setCurrentTree(TreeModel tree)
269   {
270     currentTree = tree;
271   }
272
273   public TreeModel getCurrentTree()
274   {
275     return currentTree;
276   }
277
278   boolean centreColumnLabels;
279
280   public boolean getCentreColumnLabels()
281   {
282     return centreColumnLabels;
283   }
284
285   public boolean followSelection = true;
286
287   /**
288    * @return true if view selection should always follow the selections
289    *         broadcast by other selection sources
290    */
291   public boolean getFollowSelection()
292   {
293     return followSelection;
294   }
295
296   @Override
297   public void sendSelection()
298   {
299     getStructureSelectionManager().sendSelection(
300             new SequenceGroup(getSelectionGroup()),
301             new ColumnSelection(getColumnSelection()),
302             new HiddenColumns(getAlignment().getHiddenColumns()), this);
303   }
304
305   /**
306    * Returns an instance of the StructureSelectionManager scoped to this applet
307    * instance.
308    * 
309    * @return
310    */
311   @Override
312   public StructureSelectionManager getStructureSelectionManager()
313   {
314     return jalview.structure.StructureSelectionManager
315             .getStructureSelectionManager(applet);
316   }
317
318   @Override
319   public boolean isNormaliseSequenceLogo()
320   {
321     return normaliseSequenceLogo;
322   }
323
324   public void setNormaliseSequenceLogo(boolean state)
325   {
326     normaliseSequenceLogo = state;
327   }
328
329   /**
330    * 
331    * @return true if alignment characters should be displayed
332    */
333   @Override
334   public boolean isValidCharWidth()
335   {
336     return validCharWidth;
337   }
338
339   public AnnotationColumnChooser getAnnotationColumnSelectionState()
340   {
341     return annotationColumnSelectionState;
342   }
343
344   public void setAnnotationColumnSelectionState(
345           AnnotationColumnChooser annotationColumnSelectionState)
346   {
347     this.annotationColumnSelectionState = annotationColumnSelectionState;
348   }
349
350   @Override
351   public void mirrorCommand(CommandI command, boolean undo,
352           StructureSelectionManager ssm, VamsasSource source)
353   {
354     // TODO refactor so this can be pulled up to superclass or controller
355     /*
356      * Do nothing unless we are a 'complement' of the source. May replace this
357      * with direct calls not via SSM.
358      */
359     if (source instanceof AlignViewportI
360             && ((AlignViewportI) source).getCodingComplement() == this)
361     {
362       // ok to continue;
363     }
364     else
365     {
366       return;
367     }
368
369     CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(),
370             getGapCharacter());
371     if (mappedCommand != null)
372     {
373       mappedCommand.doCommand(null);
374       firePropertyChange("alignment", null, getAlignment().getSequences());
375
376       // ap.scalePanelHolder.repaint();
377       // ap.repaint();
378     }
379   }
380
381   @Override
382   public VamsasSource getVamsasSource()
383   {
384     return this;
385   }
386
387   /**
388    * If this viewport has a (Protein/cDNA) complement, then scroll the
389    * complementary alignment to match this one.
390    */
391   public void scrollComplementaryAlignment(AlignmentPanel complementPanel)
392   {
393     if (complementPanel == null)
394     {
395       return;
396     }
397
398     /*
399      * Populate a SearchResults object with the mapped location to scroll to. If
400      * there is no complement, or it is not following highlights, or no mapping
401      * is found, the result will be empty.
402      */
403     SearchResultsI sr = new SearchResults();
404     int seqOffset = findComplementScrollTarget(sr);
405     if (!sr.isEmpty())
406     {
407       complementPanel.setToScrollComplementPanel(false);
408       complementPanel.scrollToCentre(sr, seqOffset);
409       complementPanel.setToScrollComplementPanel(true);
410     }
411   }
412
413   /**
414    * Applies the supplied feature settings descriptor to currently known
415    * features. This supports an 'initial configuration' of feature colouring
416    * based on a preset or user favourite. This may then be modified in the usual
417    * way using the Feature Settings dialogue.
418    * 
419    * @param featureSettings
420    */
421   @Override
422   public void applyFeaturesStyle(FeatureSettingsModelI featureSettings)
423   {
424     // TODO implement for applet
425   }
426
427 }