JAL-1706 fixed to correctly restore the last dialog selection after
[jalview.git] / src / jalview / gui / FontChooser.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.gui;
22
23 import java.awt.Font;
24 import java.awt.FontMetrics;
25 import java.awt.event.ActionEvent;
26
27 import javax.swing.JInternalFrame;
28 import javax.swing.JLayeredPane;
29 import javax.swing.JOptionPane;
30
31 import jalview.bin.Cache;
32 import jalview.jbgui.GFontChooser;
33 import jalview.util.MessageManager;
34
35 /**
36  * DOCUMENT ME!
37  * 
38  * @author $author$
39  * @version $Revision$
40  */
41 public class FontChooser extends GFontChooser
42 {
43   AlignmentPanel ap;
44
45   TreePanel tp;
46
47   /*
48    * The font on opening the dialog (to be restored on Cancel)
49    */
50   Font oldFont;
51
52   boolean oldProteinScale;
53
54   boolean init = true;
55
56   JInternalFrame frame;
57
58   /*
59    * The last font settings selected in the dialog
60    */
61   private Font lastSelected = null;
62
63   private boolean lastSelMono = false;
64
65   /**
66    * Creates a new FontChooser object.
67    * 
68    * @param ap
69    *          DOCUMENT ME!
70    */
71   public FontChooser(TreePanel tp)
72   {
73     this.tp = tp;
74     ap = tp.treeCanvas.ap;
75     oldFont = tp.getTreeFont();
76     defaultButton.setVisible(false);
77     smoothFont.setEnabled(false);
78     init();
79   }
80
81   /**
82    * Creates a new FontChooser object.
83    * 
84    * @param ap
85    *          DOCUMENT ME!
86    */
87   public FontChooser(AlignmentPanel ap)
88   {
89     oldFont = ap.av.getFont();
90     oldProteinScale = ap.av.isScaleProteinAsCdna();
91
92     this.ap = ap;
93     init();
94   }
95
96   void init()
97   {
98     frame = new JInternalFrame();
99     frame.setContentPane(this);
100
101     smoothFont.setSelected(ap.av.antiAlias);
102
103     /*
104      * Enable 'scale protein as cDNA' in a SplitFrame view. The selection is
105      * stored in the ViewStyle of both dna and protein Viewport
106      */
107     scaleAsCdna.setEnabled(false);
108     if (ap.av.getCodingComplement() != null)
109     {
110       scaleAsCdna.setEnabled(true);
111       scaleAsCdna.setVisible(true);
112       scaleAsCdna.setSelected(ap.av.isScaleProteinAsCdna());
113     }
114
115     if (tp != null)
116     {
117       Desktop.addInternalFrame(frame,
118               MessageManager.getString("action.change_font_tree_panel"),
119               400, 200, false);
120     }
121     else
122     {
123       Desktop.addInternalFrame(frame,
124               MessageManager.getString("action.change_font"), 380, 200,
125               false);
126     }
127
128     frame.setLayer(JLayeredPane.PALETTE_LAYER);
129
130     String[] fonts = java.awt.GraphicsEnvironment
131             .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
132
133     for (int i = 0; i < fonts.length; i++)
134     {
135       fontName.addItem(fonts[i]);
136     }
137
138     for (int i = 1; i < 51; i++)
139     {
140       fontSize.addItem(i);
141     }
142
143     fontStyle.addItem("plain");
144     fontStyle.addItem("bold");
145     fontStyle.addItem("italic");
146
147     fontName.setSelectedItem(oldFont.getName());
148     fontSize.setSelectedItem(oldFont.getSize());
149     fontStyle.setSelectedIndex(oldFont.getStyle());
150
151     FontMetrics fm = getGraphics().getFontMetrics(oldFont);
152     monospaced.setSelected(fm.getStringBounds("M", getGraphics())
153             .getWidth() == fm.getStringBounds("|", getGraphics())
154             .getWidth());
155
156     init = false;
157   }
158
159   public void smoothFont_actionPerformed(ActionEvent e)
160   {
161     ap.av.antiAlias = smoothFont.isSelected();
162     ap.getAnnotationPanel().image = null;
163     ap.paintAlignment(true);
164   }
165
166   /**
167    * DOCUMENT ME!
168    * 
169    * @param e
170    *          DOCUMENT ME!
171    */
172   protected void ok_actionPerformed(ActionEvent e)
173   {
174     try
175     {
176       frame.setClosed(true);
177     } catch (Exception ex)
178     {
179     }
180
181     if (ap != null)
182     {
183       if (ap.getOverviewPanel() != null)
184       {
185         ap.getOverviewPanel().updateOverviewImage();
186       }
187     }
188   }
189
190   /**
191    * DOCUMENT ME!
192    * 
193    * @param e
194    *          DOCUMENT ME!
195    */
196   protected void cancel_actionPerformed(ActionEvent e)
197   {
198     if (ap != null)
199     {
200       ap.av.setFont(oldFont, true);
201       ap.av.setScaleProteinAsCdna(oldProteinScale);
202       ap.paintAlignment(true);
203       if (scaleAsCdna.isEnabled())
204       {
205         ap.av.setScaleProteinAsCdna(oldProteinScale);
206         ap.av.getCodingComplement().setScaleProteinAsCdna(oldProteinScale);
207       }
208     }
209     else if (tp != null)
210     {
211       tp.setTreeFont(oldFont);
212     }
213     fontName.setSelectedItem(oldFont.getName());
214     fontSize.setSelectedItem(oldFont.getSize());
215     fontStyle.setSelectedIndex(oldFont.getStyle());
216
217     try
218     {
219       frame.setClosed(true);
220     } catch (Exception ex)
221     {
222     }
223   }
224
225   /**
226    * DOCUMENT ME!
227    */
228   void changeFont()
229   {
230     if (lastSelected == null)
231     {
232       // initialise with original font
233       lastSelected = oldFont;
234       FontMetrics fm = getGraphics().getFontMetrics(oldFont);
235       double mw = fm.getStringBounds("M", getGraphics()).getWidth();
236       double iw = fm.getStringBounds("I", getGraphics()).getWidth();
237       lastSelMono = (mw == iw); // == on double - flaky?
238     }
239
240     Font newFont = new Font(fontName.getSelectedItem().toString(),
241             fontStyle.getSelectedIndex(),
242             (Integer) fontSize.getSelectedItem());
243     FontMetrics fm = getGraphics().getFontMetrics(newFont);
244     double mw = fm.getStringBounds("M", getGraphics()).getWidth(), iw = fm
245             .getStringBounds("I", getGraphics()).getWidth();
246     if (mw < 1 || iw < 1)
247     {
248       JOptionPane
249               .showInternalMessageDialog(
250                       this,
251                       MessageManager.getString("label.font_doesnt_have_letters_defined"),
252                       MessageManager.getString("label.invalid_font"), JOptionPane.WARNING_MESSAGE);
253       /*
254        * Restore the changed value - note this will reinvoke this method via the
255        * ActionListener, but now validation should pass
256        */
257       if (lastSelected.getSize() != (Integer) fontSize.getSelectedItem()) // autoboxing
258       {
259         fontSize.setSelectedItem(lastSelected.getSize());
260       }
261       if (!lastSelected.getName().equals(
262               fontName.getSelectedItem().toString()))
263       {
264         fontName.setSelectedItem(lastSelected.getName());
265       }
266       if (lastSelected.getStyle() != fontStyle.getSelectedIndex())
267       {
268         fontStyle.setSelectedIndex(lastSelected.getStyle());
269       }
270       if (lastSelMono != monospaced.isSelected())
271       {
272         monospaced.setSelected(lastSelMono);
273       }
274       return;
275     }
276     if (tp != null)
277     {
278       tp.setTreeFont(newFont);
279     }
280     else if (ap != null)
281     {
282       ap.av.setFont(newFont, true);
283       ap.fontChanged();
284     }
285
286     monospaced.setSelected(mw == iw);
287
288     /*
289      * Remember latest valid selection, so it can be restored if followed by an
290      * invalid one
291      */
292     lastSelected = newFont;
293   }
294
295   /**
296    * DOCUMENT ME!
297    * 
298    * @param e
299    *          DOCUMENT ME!
300    */
301   protected void fontName_actionPerformed(ActionEvent e)
302   {
303     if (init)
304     {
305       return;
306     }
307
308     changeFont();
309   }
310
311   /**
312    * DOCUMENT ME!
313    * 
314    * @param e
315    *          DOCUMENT ME!
316    */
317   protected void fontSize_actionPerformed(ActionEvent e)
318   {
319     if (init)
320     {
321       return;
322     }
323
324     changeFont();
325   }
326
327   /**
328    * DOCUMENT ME!
329    * 
330    * @param e
331    *          DOCUMENT ME!
332    */
333   protected void fontStyle_actionPerformed(ActionEvent e)
334   {
335     if (init)
336     {
337       return;
338     }
339
340     changeFont();
341   }
342
343   /**
344    * Make selected settings the defaults by storing them (via Cache class) in
345    * the .jalview_properties file (the file is only written when Jalview exits)
346    * 
347    * @param e
348    */
349   public void defaultButton_actionPerformed(ActionEvent e)
350   {
351     Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());
352     Cache.setProperty("FONT_STYLE", fontStyle.getSelectedIndex() + "");
353     Cache.setProperty("FONT_SIZE", fontSize.getSelectedItem().toString());
354     Cache.setProperty("ANTI_ALIAS",
355             Boolean.toString(smoothFont.isSelected()));
356     Cache.setProperty(Preferences.SCALE_PROTEIN_TO_CDNA,
357             Boolean.toString(scaleAsCdna.isSelected()));
358   }
359
360   /**
361    * Turn on/off scaling of protein characters to 3 times the width of cDNA
362    * characters
363    */
364   @Override
365   protected void scaleAsCdna_actionPerformed(ActionEvent e)
366   {
367     ap.av.setScaleProteinAsCdna(scaleAsCdna.isSelected());
368     ap.av.getCodingComplement().setScaleProteinAsCdna(
369             scaleAsCdna.isSelected());
370     final SplitFrame splitFrame = (SplitFrame) ap.alignFrame
371             .getSplitViewContainer();
372     splitFrame.adjustLayout();
373     splitFrame.repaint();
374     // ap.paintAlignment(true);
375     // TODO would like to repaint
376   }
377 }