JAL-3187 nice to have enabling/disabling of apply/cancel when feature settings have...
[jalview.git] / src / jalview / gui / FeatureSettings.java
index 4dca630..dc7283b 100644 (file)
@@ -82,6 +82,7 @@ import java.util.Map;
 import java.util.Set;
 
 import javax.help.HelpSetException;
+import javax.swing.AbstractButton;
 import javax.swing.AbstractCellEditor;
 import javax.swing.BorderFactory;
 import javax.swing.Icon;
@@ -183,6 +184,16 @@ public class FeatureSettings extends JPanel
    */
   Map<String, float[]> typeWidth = null;
 
+  private void storeOriginalSettings()
+  {
+    // save transparency for restore on Cancel
+    originalTransparency = fr.getTransparency();
+    int originalTransparencyAsPercent = (int) (originalTransparency * 100);
+    transparency.setMaximum(100 - originalTransparencyAsPercent);
+
+    originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy
+    originalViewStyle = new ViewStyle(af.viewport.getViewStyle());
+  }
   /**
    * Constructor
    * 
@@ -192,15 +203,7 @@ public class FeatureSettings extends JPanel
   {
     this.af = alignFrame;
     fr = af.getFeatureRenderer();
-
-    // save transparency for restore on Cancel
-    originalTransparency = fr.getTransparency();
-    int originalTransparencyAsPercent = (int) (originalTransparency * 100);
-    transparency.setMaximum(100 - originalTransparencyAsPercent);
-
-    originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy
-    originalViewStyle = new ViewStyle(af.viewport.getViewStyle());
-
+    storeOriginalSettings();
     try
     {
       jbInit();
@@ -385,17 +388,36 @@ public class FeatureSettings extends JPanel
     {
       frame = new JInternalFrame();
       frame.setContentPane(this);
-      if (Platform.isAMac())
+      Rectangle bounds = af.getFeatureSettingsGeometry();
+      String title;
+      if (af.getAlignPanels().size() > 1 || Desktop.getAlignmentPanels(
+              af.alignPanel.av.getSequenceSetId()).length > 1)
       {
-        Desktop.addInternalFrame(frame,
-                MessageManager.getString("label.sequence_feature_settings"),
-                600, 480);
+        title = MessageManager.formatMessage(
+                "label.sequence_feature_settings_for_view",
+                af.alignPanel.getViewName());
       }
       else
       {
-        Desktop.addInternalFrame(frame,
-                MessageManager.getString("label.sequence_feature_settings"),
-                600, 450);
+        title = MessageManager.getString("label.sequence_feature_settings");
+      }
+      if (bounds == null)
+      {
+        if (Platform.isAMac())
+        {
+          Desktop.addInternalFrame(frame, title, 600, 480);
+        }
+        else
+        {
+          Desktop.addInternalFrame(frame, title, 600, 450);
+        }
+      }
+      else
+      {
+        Desktop.addInternalFrame(frame, title,
+                false, bounds.width, bounds.height);
+        frame.setBounds(bounds);
+        frame.setVisible(true);
       }
       frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
 
@@ -406,7 +428,7 @@ public class FeatureSettings extends JPanel
                 public void internalFrameClosed(
                         javax.swing.event.InternalFrameEvent evt)
                 {
-                  closeFeatureSettings();
+                  featureSettings_isClosed();
                 };
               });
       frame.setLayer(JLayeredPane.PALETTE_LAYER);
@@ -416,6 +438,17 @@ public class FeatureSettings extends JPanel
 
   PropertyChangeListener change;
 
+  private JCheckBox showComplementOnTop;
+
+  private AbstractButton showComplement;
+
+  private void updateComplementButtons()
+  {
+    showComplement.setSelected(af.getViewport().isShowComplementFeatures());
+    showComplementOnTop
+            .setSelected(af.getViewport().isShowComplementFeaturesOnTop());
+  }
+
   @Override
   public AlignViewControllerGuiI getAlignframe()
   {
@@ -423,7 +456,7 @@ public class FeatureSettings extends JPanel
   }
 
   @Override
-  public void closeFeatureSettings()
+  public void featureSettings_isClosed()
   {
     fr.removePropertyChangeListener(change);
     change = null;
@@ -1104,18 +1137,36 @@ public class FeatureSettings extends JPanel
     table.repaint();
   }
 
+  /**
+   * close ourselves but leave any existing UI handlers (e.g a CDS/Protein tabbed
+   * feature settings dialog) intact
+   */
+  public void closeOldSettings()
+  {
+    closeDialog(false);
+  }
+
+  /**
+   * close the feature settings dialog (and any containing frame)
+   */
   public void close()
   {
+    closeDialog(true);
+  }
+
+  private void closeDialog(boolean closeContainingFrame)
+  {
     try
     {
       if (frame != null)
       {
+        af.setFeatureSettingsGeometry(frame.getBounds());
         frame.setClosed(true);
       }
       else
       {
         SplitContainerI sc = af.getSplitViewContainer();
-        sc.closeFeatureSettings(this);
+        sc.closeFeatureSettings(this, closeContainingFrame);
         af.featureSettings = null;
       }
     } catch (Exception exe)
@@ -1168,6 +1219,9 @@ public class FeatureSettings extends JPanel
   {
     this.setLayout(new BorderLayout());
 
+    final boolean hasComplement = af.getViewport()
+            .getCodingComplement() != null;
+
     JPanel settingsPane = new JPanel();
     settingsPane.setLayout(new BorderLayout());
 
@@ -1240,30 +1294,47 @@ public class FeatureSettings extends JPanel
         }
       }
     });
-
-    JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+    // Cancel for a SplitFrame should just revert changes to the currently displayed
+    // settings. May want to do this for either or both - so need a splitview
+    // feature settings cancel/OK.
+    JButton cancel = new JButton(MessageManager
+            .getString(hasComplement ? "action.revert" : "action.cancel"));
+    cancel.setToolTipText(MessageManager.getString(hasComplement
+            ? "action.undo_changes_to_feature_settings"
+            : "action.undo_changes_to_feature_settings_and_close_the_dialog"));
     cancel.setFont(JvSwingUtils.getLabelFont());
+    // TODO: disable cancel (and apply!) until current settings are different
     cancel.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        fr.setTransparency(originalTransparency);
-        fr.setFeatureFilters(originalFilters);
-        updateFeatureRenderer(originalData);
-        af.getViewport().setViewStyle(originalViewStyle);
-        close();
+        revert();
+        if (!hasComplement)
+        {
+          close();
+        }
       }
     });
-
-    JButton ok = new JButton(MessageManager.getString("action.ok"));
+    // Cancel for the whole dialog should cancel both CDS and Protein.
+    // OK for an individual feature settings just applies changes, but dialog
+    // remains open
+    JButton ok = new JButton(MessageManager
+            .getString(hasComplement ? "action.apply" : "action.ok"));
     ok.setFont(JvSwingUtils.getLabelFont());
     ok.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        close();
+        if (!hasComplement)
+        {
+          close();
+        }
+        else
+        {
+          storeOriginalSettings();
+        }
       }
     });
 
@@ -1317,8 +1388,7 @@ public class FeatureSettings extends JPanel
                     ? MessageManager.getString("label.protein")
                             .toLowerCase()
                     : "CDS");
-    JCheckBox showComplement = new JCheckBox(text);
-    showComplement.setSelected(af.getViewport().isShowComplementFeatures());
+    showComplement = new JCheckBox(text);
     showComplement.addActionListener(new ActionListener()
     {
       @Override
@@ -1330,10 +1400,8 @@ public class FeatureSettings extends JPanel
       }
     });
 
-    JCheckBox showComplementOnTop = new JCheckBox(
+    showComplementOnTop = new JCheckBox(
             MessageManager.getString("label.on_top"));
-    showComplementOnTop
-            .setSelected(af.getViewport().isShowComplementFeaturesOnTop());
     showComplementOnTop.addActionListener(new ActionListener()
     {
       @Override
@@ -1386,7 +1454,6 @@ public class FeatureSettings extends JPanel
     transbuttons.add(sortByDens);
     transbuttons.add(help);
 
-    boolean hasComplement = af.getViewport().getCodingComplement() != null;
     JPanel transPanelLeft = new JPanel(
             new GridLayout(hasComplement ? 4 : 2, 1));
     transPanelLeft.add(new JLabel(" Colour transparency" + ":"));
@@ -1968,6 +2035,26 @@ public class FeatureSettings extends JPanel
       return button;
     }
   }
+
+  public boolean isOpen()
+  {
+    if (af.getSplitViewContainer() != null)
+    {
+      return af.getSplitViewContainer().isFeatureSettingsOpen();
+    }
+    return frame != null && !frame.isClosed();
+  }
+
+  @Override
+  public void revert()
+  {
+    fr.setTransparency(originalTransparency);
+    fr.setFeatureFilters(originalFilters);
+    updateFeatureRenderer(originalData);
+    af.getViewport().setViewStyle(originalViewStyle);
+    updateComplementButtons();
+    refreshDisplay();
+  }
 }
 
 class FeatureIcon implements Icon