/*
 * Autopsy Forensic Browser
 *
 * Copyright 2011-2016 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.autopsy.timeline.ui.listvew;

import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import javax.swing.SwingUtilities;

/**
 * Allows creation of JavaFX menus with the same structure as Swing menus and
 * which invoke the same actions.
 */
public class SwingFXMenuUtils extends MenuItem {

    /**
     * Factory method that creates a JavaFX MenuItem backed by a MenuElement
     *
     * @param jMenuElement The MenuElement to create a JavaFX menu for.
     *
     * @return a MenuItem for the given MenuElement
     */
    public static MenuItem createFXMenu(MenuElement jMenuElement) {
        if (jMenuElement == null) {
            //Since null is sometime used to represenet a seperator, follow that convention.
            return new SeparatorMenuItem();
        } else if (jMenuElement instanceof JMenu) {
            return new MenuAdapter((JMenu) jMenuElement);
        } else if (jMenuElement instanceof JPopupMenu) {
            return new MenuAdapter((JPopupMenu) jMenuElement);
        } else {
            return new MenuItemAdapter((JMenuItem) jMenuElement);
        }
    }

    /**
     * A JavaFX MenuItem that invokes the backing JMenuItem when clicked.
     */
    private static class MenuItemAdapter extends MenuItem {

        private MenuItemAdapter(final JMenuItem jMenuItem) {
            super(jMenuItem.getText());
            setOnAction(actionEvent -> SwingUtilities.invokeLater(jMenuItem::doClick));
        }
    }

    /**
     * A JavaFX Menu that has the same structure as a given Swing JMenu or
     * JPopupMenu.
     */
    private static class MenuAdapter extends Menu {

        /**
         * Constructor for JMenu
         *
         * @param jMenu The JMenu to parallel in this Menu.
         */
        MenuAdapter(final JMenu jMenu) {
            super(jMenu.getText());
            populateSubMenus(jMenu);
        }

        /**
         * Constructor for JPopupMenu
         *
         * @param jPopupMenu The JPopupMenu to parallel in this Menu.
         */
        MenuAdapter(JPopupMenu jPopupMenu) {
            super(jPopupMenu.getLabel());
            populateSubMenus(jPopupMenu);
        }

        /**
         * Populate the sub menus of this menu.
         *
         * @param menu The MenuElement whose sub elements will be used to
         *             populate the sub menus of this menu.
         */
        private void populateSubMenus(MenuElement menu) {
            for (MenuElement menuElement : menu.getSubElements()) {
                if (menuElement == null) {
                    //Since null is sometime used to represenet a seperator, follow that convention.
                    getItems().add(new SeparatorMenuItem());

                } else if (menuElement instanceof JMenuItem) {
                    getItems().add(SwingFXMenuUtils.createFXMenu(menuElement));

                } else if (menuElement instanceof JPopupMenu) {
                    populateSubMenus(menuElement);

                } else {
                    throw new UnsupportedOperationException("Unown MenuElement subclass: " + menuElement.getClass().getName());
                }
            }
        }
    }
}

@@ -52,9 +52,9 @@
 -201
-6
+8
  Bas
@@ -1126,22 +1126,16 @@
 ns.%0A */%0A
-public
  class S
@@ -1150,34 +1150,57 @@
 nuUtils 
-extends MenuItem %7B
+%7B%0A%0A    private SwingFXMenuUtils() %7B%0A    %7D
 %0A%0A    /*
@@ -1266,16 +1266,22 @@
 ed by a 
+swing 
 MenuElem
@@ -2245,32 +2245,88 @@
 tem.getText());%0A
+            setDisable(jMenuItem.isEnabled() == false);%0A
             setO
@@ -2774,32 +2774,84 @@
 enu.getText());%0A
+            setDisable(jMenu.isEnabled() == false);%0A
             popu
@@ -3108,24 +3108,81 @@
 etLabel());%0A
+            setDisable(jPopupMenu.isEnabled() == false);%0A
             
@@ -4232,10 +4232,11 @@
 %7D%0A    %7D%0A
+%0A
 %7D%0A

disable menus appropriately in timeline list view