From 133b0c4350d311bd603e6468a6a47086bbc50b13 Mon Sep 17 00:00:00 2001
From: tcarver <tjc>
Date: Wed, 7 Sep 2011 10:43:22 +0100
Subject: [PATCH] shortcut changed in Preferences are saved between sessions

---
 .../sanger/artemis/components/EntryEdit.java  |   4 +-
 .../artemis/components/SelectionMenu.java     |  67 +++++----
 uk/ac/sanger/artemis/components/ShortCut.java | 134 ++++++++++++++++++
 3 files changed, 177 insertions(+), 28 deletions(-)
 create mode 100644 uk/ac/sanger/artemis/components/ShortCut.java

diff --git a/uk/ac/sanger/artemis/components/EntryEdit.java b/uk/ac/sanger/artemis/components/EntryEdit.java
index d494c909c..a8ff85429 100644
--- a/uk/ac/sanger/artemis/components/EntryEdit.java
+++ b/uk/ac/sanger/artemis/components/EntryEdit.java
@@ -1546,9 +1546,7 @@ public class EntryEdit extends JFrame
         {
           JMenu menu = EntryEdit.super.getJMenuBar().getMenu(i);
           if(menu instanceof SelectionMenu &&
-             ( menu instanceof SelectMenu ||
-               menu instanceof EditMenu ||
-               menu instanceof ViewMenu ))
+            ((SelectionMenu)menu).isEditableShortCutMenu() )
             shortcut_pane.add(menu.getText()+" Menu", ((SelectionMenu)menu).getShortCuts());
         }
         
diff --git a/uk/ac/sanger/artemis/components/SelectionMenu.java b/uk/ac/sanger/artemis/components/SelectionMenu.java
index 1caa66cf0..5eeb9c74e 100644
--- a/uk/ac/sanger/artemis/components/SelectionMenu.java
+++ b/uk/ac/sanger/artemis/components/SelectionMenu.java
@@ -30,6 +30,7 @@ import uk.ac.sanger.artemis.*;
 
 import java.awt.event.*;
 import javax.swing.*;
+
 import java.awt.*;
 import java.util.Vector;
 
@@ -49,7 +50,7 @@ public class SelectionMenu extends JMenu
   private static final long serialVersionUID = 1L;
 
   /** The Selection that was passed to the constructor. */
-  /* final */ private Selection selection;
+  private Selection selection;
 
   /** The JFrame reference that was passed to the constructor. */
   private JFrame frame = null;
@@ -405,34 +406,25 @@ public class SelectionMenu extends JMenu
     else
     {
       char c[] = ((String)combo.getSelectedItem()).toCharArray();
-      int modifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
-
-      if( ((String)mod_combo.getSelectedItem()).equals("Alt") )
-        modifier = InputEvent.ALT_MASK;
-      else if( ((String)mod_combo.getSelectedItem()).equals("Ctrl") )
-        modifier = InputEvent.CTRL_MASK;
-      else if( ((String)mod_combo.getSelectedItem()).equals("Shift") )
-        modifier = InputEvent.SHIFT_MASK;
-
+      int modifier = getModifierFromString((String)mod_combo.getSelectedItem()); 
       mi.setAccelerator(KeyStroke.getKeyStroke(c[0], modifier));
-      mi.setText(mi.getText());
-      mi.revalidate();
-      mi.repaint();
     }
-  }
 
-/*  public void getAccelerators()
+    if(ShortCut.usingCache())
+      new ShortCut(getText(), mi.getText(), mi.getAccelerator());
+  }
+  
+  private int getModifierFromString(String modStr)
   {
-    Hashtable keyStrokeHash = new Hashtable();
-    Component menus[] = getMenuComponents();
-    for(int i = 0; i < menus.length; i++)
-    {
-      JMenuItem menu = (JMenuItem)menus[i];
-      KeyStroke ks = menu.getAccelerator();
-      if(ks != null)
-        keyStrokeHash.put(menu.getText(), ks);
-    }
-  }*/
+    int modifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+    if( modStr.equals("Alt") )
+      modifier = InputEvent.ALT_MASK;
+    else if( modStr.equals("Ctrl") )
+      modifier = InputEvent.CTRL_MASK;
+    else if( modStr.equals("Shift") )
+      modifier = InputEvent.SHIFT_MASK;
+    return modifier;
+  }
   
   public static String getKeyText(int keyCode)
   {
@@ -461,5 +453,30 @@ public class SelectionMenu extends JMenu
     
     return "unknown(0x" + Integer.toString(keyCode, 16) + ")";
   }
+  
+  /**
+   * True if this menu has editable shortcuts
+   * @return
+   */
+  protected boolean isEditableShortCutMenu()
+  {
+    if(this instanceof SelectMenu ||
+       this instanceof EditMenu ||
+       this instanceof ViewMenu )
+      return true;
+    return false;
+  }
+  
+  /**
+   * Override to apply any cached shortcuts
+   */
+  public JMenuItem add(JMenuItem menuItem)
+  {
+    JMenuItem mi = super.add(menuItem);
+    if(isEditableShortCutMenu() && ShortCut.usingCache())
+      ShortCut.applyShortCutFromCache(getText(), menuItem);
+    return mi;
+  }
+  
 }
 
diff --git a/uk/ac/sanger/artemis/components/ShortCut.java b/uk/ac/sanger/artemis/components/ShortCut.java
new file mode 100644
index 000000000..5529f53e2
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/ShortCut.java
@@ -0,0 +1,134 @@
+/* ShortCut.java
+ *
+ * This file is part of Artemis
+ *
+ * Copyright(C) 2011  Genome Research Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or(at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+package uk.ac.sanger.artemis.components;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+
+import uk.ac.sanger.artemis.Options;
+import uk.ac.sanger.artemis.components.database.DatabaseJPanel;
+
+/**
+ * Used to cache shortcut keystroke between sessions
+ */
+class ShortCut implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  private String shortCutName;
+  private String menuName;
+  private KeyStroke ks;
+  private static org.apache.log4j.Logger logger4j = 
+      org.apache.log4j.Logger.getLogger(DatabaseJPanel.class);
+  private static String SHORTCUT_CACHE_PATH = Options.CACHE_PATH + File.separatorChar + "MenuShortCuts";
+  private static String REGEXP_REPLACE = "[ /]";
+    
+  ShortCut(final String menuName, final String shortCutName, final KeyStroke ks)
+  {
+    this.menuName = menuName;
+    this.shortCutName = shortCutName;
+    this.ks = ks;
+    writeCache();
+  }
+    
+  private void writeCache()
+  {
+    try
+    {
+      File dir = new File(SHORTCUT_CACHE_PATH);
+      if(!dir.exists())
+        dir.mkdirs();
+      FileOutputStream fos = new FileOutputStream(SHORTCUT_CACHE_PATH +
+          File.separatorChar + menuName + ":" + shortCutName.replaceAll(REGEXP_REPLACE, "_"));
+      ObjectOutputStream out = new ObjectOutputStream(fos);
+      out.writeObject(ShortCut.this);
+      out.close();
+    }
+    catch(Exception ex)
+    {
+      ex.getMessage();
+    }
+  }
+  
+  /**
+   * Return true if shortcut_cache flag is set.
+   * @return
+   */
+  protected static boolean usingCache()
+  {
+    return Options.getOptions().getPropertyTruthValue("shortcut_cache");
+  }
+  
+  private static File[] getCachedShortCuts()
+  {
+    File cacheDir = new File(SHORTCUT_CACHE_PATH);
+    if(cacheDir.exists())
+      return cacheDir.listFiles();
+    return null;
+  }
+
+  protected static void applyShortCutFromCache(final String menuName, final JMenuItem menuItem)
+  {
+    File[] shorts = getCachedShortCuts();
+    if(shorts != null)
+    {
+      String shortCutName = menuItem.getText();
+      for(int i=0; i<shorts.length; i++)
+      {
+        if(shorts[i].getName().equals(menuName + ":" + shortCutName.replaceAll(REGEXP_REPLACE, "_")))
+        {
+          try
+          {
+            FileInputStream fis = new FileInputStream(shorts[i]);
+            ObjectInputStream in = new ObjectInputStream(fis);
+            ShortCut sc = (ShortCut) in.readObject();
+            in.close();
+            menuItem.setAccelerator(sc.ks);
+            
+            logger4j.debug("USING CACHED SHORTCUT ("+menuItem.getText()+
+                ") FROM: "+shorts[i].getAbsolutePath());
+          }
+          catch (FileNotFoundException e)
+          {
+            System.err.println(e.getMessage());
+          }
+          catch (IOException e)
+          {
+            System.err.println(e.getMessage());
+          }
+          catch (ClassNotFoundException e)
+          {
+            System.err.println(e.getMessage());
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
-- 
GitLab