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