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