<commit_before>package nl.mpi.kinnate.ui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.ArrayList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import nl.mpi.arbil.data.ArbilDataNodeLoader;
import nl.mpi.arbil.ui.ArbilWindowManager;
import nl.mpi.arbil.userstorage.SessionStorage;
import nl.mpi.arbil.util.BugCatcherManager;
import nl.mpi.kinnate.entityindexer.EntityCollection;
import nl.mpi.kinnate.gedcomimport.ImportException;
import nl.mpi.kinnate.kindata.DataTypes.RelationType;
import nl.mpi.kinnate.kindocument.EntityDocument;
import nl.mpi.kinnate.kindocument.EntityMerger;
import nl.mpi.kinnate.kindocument.ImportTranslator;
import nl.mpi.kinnate.kindocument.RelationLinker;
import nl.mpi.kinnate.svg.DataStoreSvg.DiagramMode;
import nl.mpi.kinnate.svg.GraphPanel;
import nl.mpi.kinnate.svg.SvgUpdateHandler;
import nl.mpi.kinnate.ui.entityprofiles.ProfileRecord;
import nl.mpi.kinnate.uniqueidentifiers.UniqueIdentifier;

/**
 * Document : GraphPanelContextMenu
 * Created on : Feb 18, 2011, 11:51:00 AM
 * Author : <NAME>
 */
public class GraphPanelContextMenu extends JPopupMenu implements ActionListener {

    private KinDiagramPanel kinDiagramPanel;
    private GraphPanel graphPanel;
    private JMenu addEntityMenu;
    private JMenuItem duplicateEntitiesMenu;
    private JMenuItem mergeEntitiesMenu;
    private JMenuItem addRelationEntityMenu;
    private JMenuItem removeRelationEntityMenu;
    private JMenuItem setAsEgoMenuItem;
    private JMenuItem addAsEgoMenuItem;
    private JMenuItem removeEgoMenuItem;
    private JMenuItem addAsRequiredMenuItem;
    private JMenuItem removeRequiredMenuItem;
    private JMenuItem saveFileMenuItem;
    private JMenuItem deleteMenu;
    final JSeparator jSeparator2 = new JSeparator();
    final JSeparator jSeparator3 = new JSeparator();
    private UniqueIdentifier[] selectedIdentifiers = null; // keep the selected paths as shown at the time of the menu intereaction
    private float xPos;
    private float yPos;
    private ArbilDataNodeLoader dataNodeLoader;

    public GraphPanelContextMenu(KinDiagramPanel egoSelectionPanelLocal, final GraphPanel graphPanelLocal, final EntityCollection entityCollection, final ArbilWindowManager arbilWindowManager, ArbilDataNodeLoader dataNodeLoaderL, final SessionStorage sessionStorage) {
        kinDiagramPanel = egoSelectionPanelLocal;
        graphPanel = graphPanelLocal;
        this.dataNodeLoader = dataNodeLoaderL;
        if (egoSelectionPanelLocal != null) {
            final ActionListener addMenuActionListener = new java.awt.event.ActionListener() {

                public void actionPerformed(final java.awt.event.ActionEvent evt) {
                    new Thread() {

                        @Override
                        public void run() {
                            // node type will be used to determine the schema used from the diagram options
                            kinDiagramPanel.showProgressBar();
                            String nodeType = evt.getActionCommand();
                            try {
                                EntityDocument entityDocument = new EntityDocument(nodeType, new ImportTranslator(true), sessionStorage);
                                entityDocument.saveDocument();
                                URI addedEntityUri = entityDocument.getFile().toURI();
                                entityCollection.updateDatabase(addedEntityUri);
                                kinDiagramPanel.addRequiredNodes(new UniqueIdentifier[]{entityDocument.getUniqueIdentifier()});
                            } catch (ImportException exception) {
                                kinDiagramPanel.clearProgressBar();
                                BugCatcherManager.getBugCatcher().logError(exception);
                                arbilWindowManager.addMessageDialogToQueue("Failed to create entity: " + exception.getMessage(), "Add Entity");
                            }
                        }
                    }.start();
                }
            };

            addEntityMenu = new JMenu("Add");
            addEntityMenu.addMenuListener(new MenuListener() {

                public void menuSelected(MenuEvent e) {
                    addEntityMenu.removeAll();
                    for (ProfileRecord profileRecord : graphPanelLocal.dataStoreSvg.selectedProfiles) {
                        JMenuItem addMenuItem = new JMenuItem(profileRecord.profileName);
                        addMenuItem.setActionCommand(profileRecord.profileId);
                        addMenuItem.addActionListener(addMenuActionListener);
                        addEntityMenu.add(addMenuItem);
                    }
                }

                public void menuDeselected(MenuEvent e) {
                }

                public void menuCanceled(MenuEvent e) {
                }
            });
            this.add(addEntityMenu);

            JMenu shapeSubMenu = new JMenu("Add Geometry");
            for (SvgUpdateHandler.GraphicsTypes graphicsType : SvgUpdateHandler.GraphicsTypes.values()) {
                JMenuItem addLabel = new JMenuItem("Add " + graphicsType.name());
                addLabel.setActionCommand(graphicsType.name());
                shapeSubMenu.add(addLabel);
                if (SvgUpdateHandler.GraphicsTypes.Polyline.equals(graphicsType)) {
                    addLabel.setEnabled(false);
                }
                addLabel.addActionListener(GraphPanelContextMenu.this);
                // todo: addthese into a layer behind the entities, athought lables could be above
                // todo: when geometry is selected construct an arbildatanode to allow the geometries attributes to be edited
            }
            this.add(shapeSubMenu);

            deleteMenu = new JMenuItem("Delete");
            deleteMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    kinDiagramPanel.showProgressBar();
                    int entityCount = 0;
                    for (UniqueIdentifier uniqueIdentifier : selectedIdentifiers) {
                        if (!uniqueIdentifier.isGraphicsIdentifier() && !uniqueIdentifier.isTransientIdentifier()) {
                            entityCount++;
                        }
                    }
                    boolean doDelete = false;
                    if (entityCount == 0) {
                        doDelete = true;
                    } else if (JOptionPane.OK_OPTION == arbilWindowManager.showDialogBox(entityCount + " entities will be deleted from the database", "Delete Entity", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
                        doDelete = true;
                    }
                    if (doDelete) {
                        ArrayList<UniqueIdentifier> affectedIdentifiers = new ArrayList<UniqueIdentifier>();
                        for (UniqueIdentifier uniqueIdentifier : selectedIdentifiers) {
                            if (uniqueIdentifier.isGraphicsIdentifier()) {
                                graphPanel.svgUpdateHandler.deleteGraphics(uniqueIdentifier);
                            } else if (uniqueIdentifier.isTransientIdentifier()) {
                                kinDiagramPanel.clearProgressBar();
                                throw new UnsupportedOperationException("Cannot delete transient entities.");
                            } else {
                                affectedIdentifiers.add(uniqueIdentifier);
                            }
                        }
                        final UniqueIdentifier[] affectedIdentifiersArray = affectedIdentifiers.toArray(new UniqueIdentifier[]{});
                        try {
                            final RelationLinker relationLinker = new RelationLinker(sessionStorage, arbilWindowManager, entityCollection);
                            relationLinker.deleteEntity(affectedIdentifiersArray);
                        } catch (ImportException exception) {
                            arbilWindowManager.addMessageDialogToQueue("Failed to delete: " + exception.getMessage(), mergeEntitiesMenu.getText());
                        }
                        kinDiagramPanel.removeRequiredNodes(affectedIdentifiersArray);
                        kinDiagramPanel.removeEgoNodes(affectedIdentifiersArray);
                    }
                    kinDiagramPanel.clearProgressBar();
                }
            });
            this.add(deleteMenu);

            mergeEntitiesMenu = new JMenuItem("Merge Selected Entities");
            mergeEntitiesMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    kinDiagramPanel.showProgressBar();
                    try {
                        final EntityMerger entityMerger = new EntityMerger(sessionStorage, arbilWindowManager, entityCollection);
                        entityMerger.mergeEntities(selectedIdentifiers);
                        kinDiagramPanel.entityRelationsChanged(entityMerger.getAffectedIdentifiersArray());
                        kinDiagramPanel.removeRequiredNodes(entityMerger.getDeletedIdentifiersArray());
                    } catch (ImportException exception) {
                        arbilWindowManager.addMessageDialogToQueue("Failed to merge: " + exception.getMessage(), mergeEntitiesMenu.getText());
                    }
                    kinDiagramPanel.clearProgressBar();
                }
            });
            this.add(mergeEntitiesMenu);

            duplicateEntitiesMenu = new JMenuItem("Duplicate Selected Entities");
            duplicateEntitiesMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    kinDiagramPanel.showProgressBar();
                    try {
                        final UniqueIdentifier[] duplicateEntities = new EntityMerger(sessionStorage, arbilWindowManager, entityCollection).duplicateEntities(selectedIdentifiers);
                        kinDiagramPanel.entityRelationsChanged(selectedIdentifiers);
                        kinDiagramPanel.addRequiredNodes(duplicateEntities);
                    } catch (ImportException exception) {
                        arbilWindowManager.addMessageDialogToQueue("Failed to duplicate: " + exception.getMessage(), duplicateEntitiesMenu.getText());
                    }
                    kinDiagramPanel.clearProgressBar();
                }
            });
            this.add(duplicateEntitiesMenu);

            addRelationEntityMenu = new JMenu("Add Relation");
            this.add(addRelationEntityMenu);
            for (RelationType relationType : RelationType.values()) {
                JMenuItem addRelationEntityMenuItem = new JMenuItem(relationType.name());
                addRelationEntityMenuItem.setActionCommand(relationType.name());
                addRelationEntityMenuItem.addActionListener(new java.awt.event.ActionListener() {
<commit_msg>Modified merge entities so that merged relations are joined correctly and no extraneous relations are left behind. Modified merge entities so that it deletes the non lead selection after merging. Added use of the diagram progress bar when deleting, merging and duplicating entities in the diagram. refs #1850 #1849 #1848 #1853<commit_after>package nl.mpi.kinnate.ui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.ArrayList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import nl.mpi.arbil.data.ArbilDataNodeLoader;
import nl.mpi.arbil.ui.ArbilWindowManager;
import nl.mpi.arbil.userstorage.SessionStorage;
import nl.mpi.arbil.util.BugCatcherManager;
import nl.mpi.kinnate.entityindexer.EntityCollection;
import nl.mpi.kinnate.gedcomimport.ImportException;
import nl.mpi.kinnate.kindata.DataTypes.RelationType;
import nl.mpi.kinnate.kindocument.EntityDocument;
import nl.mpi.kinnate.kindocument.EntityMerger;
import nl.mpi.kinnate.kindocument.ImportTranslator;
import nl.mpi.kinnate.kindocument.RelationLinker;
import nl.mpi.kinnate.svg.DataStoreSvg.DiagramMode;
import nl.mpi.kinnate.svg.GraphPanel;
import nl.mpi.kinnate.svg.SvgUpdateHandler;
import nl.mpi.kinnate.ui.entityprofiles.ProfileRecord;
import nl.mpi.kinnate.uniqueidentifiers.UniqueIdentifier;

/**
 * Document : GraphPanelContextMenu
 * Created on : Feb 18, 2011, 11:51:00 AM
 * Author : <NAME>
 */
public class GraphPanelContextMenu extends JPopupMenu implements ActionListener {

    private KinDiagramPanel kinDiagramPanel;
    private GraphPanel graphPanel;
    private JMenu addEntityMenu;
    private JMenuItem duplicateEntitiesMenu;
    private JMenuItem mergeEntitiesMenu;
    private JMenuItem addRelationEntityMenu;
    private JMenuItem removeRelationEntityMenu;
    private JMenuItem setAsEgoMenuItem;
    private JMenuItem addAsEgoMenuItem;
    private JMenuItem removeEgoMenuItem;
    private JMenuItem addAsRequiredMenuItem;
    private JMenuItem removeRequiredMenuItem;
    private JMenuItem saveFileMenuItem;
    private JMenuItem deleteMenu;
    final JSeparator jSeparator2 = new JSeparator();
    final JSeparator jSeparator3 = new JSeparator();
    private UniqueIdentifier[] selectedIdentifiers = null; // keep the selected paths as shown at the time of the menu intereaction
    private float xPos;
    private float yPos;
    private ArbilDataNodeLoader dataNodeLoader;

    public GraphPanelContextMenu(KinDiagramPanel egoSelectionPanelLocal, final GraphPanel graphPanelLocal, final EntityCollection entityCollection, final ArbilWindowManager arbilWindowManager, ArbilDataNodeLoader dataNodeLoaderL, final SessionStorage sessionStorage) {
        kinDiagramPanel = egoSelectionPanelLocal;
        graphPanel = graphPanelLocal;
        this.dataNodeLoader = dataNodeLoaderL;
        if (egoSelectionPanelLocal != null) {
            final ActionListener addMenuActionListener = new java.awt.event.ActionListener() {

                public void actionPerformed(final java.awt.event.ActionEvent evt) {
                    new Thread() {

                        @Override
                        public void run() {
                            // node type will be used to determine the schema used from the diagram options
                            kinDiagramPanel.showProgressBar();
                            String nodeType = evt.getActionCommand();
                            try {
                                EntityDocument entityDocument = new EntityDocument(nodeType, new ImportTranslator(true), sessionStorage);
                                entityDocument.saveDocument();
                                URI addedEntityUri = entityDocument.getFile().toURI();
                                entityCollection.updateDatabase(addedEntityUri);
                                kinDiagramPanel.addRequiredNodes(new UniqueIdentifier[]{entityDocument.getUniqueIdentifier()});
                            } catch (ImportException exception) {
                                kinDiagramPanel.clearProgressBar();
                                BugCatcherManager.getBugCatcher().logError(exception);
                                arbilWindowManager.addMessageDialogToQueue("Failed to create entity: " + exception.getMessage(), "Add Entity");
                            }
                        }
                    }.start();
                }
            };

            addEntityMenu = new JMenu("Add");
            addEntityMenu.addMenuListener(new MenuListener() {

                public void menuSelected(MenuEvent e) {
                    addEntityMenu.removeAll();
                    for (ProfileRecord profileRecord : graphPanelLocal.dataStoreSvg.selectedProfiles) {
                        JMenuItem addMenuItem = new JMenuItem(profileRecord.profileName);
                        addMenuItem.setActionCommand(profileRecord.profileId);
                        addMenuItem.addActionListener(addMenuActionListener);
                        addEntityMenu.add(addMenuItem);
                    }
                }

                public void menuDeselected(MenuEvent e) {
                }

                public void menuCanceled(MenuEvent e) {
                }
            });
            this.add(addEntityMenu);

            JMenu shapeSubMenu = new JMenu("Add Geometry");
            for (SvgUpdateHandler.GraphicsTypes graphicsType : SvgUpdateHandler.GraphicsTypes.values()) {
                JMenuItem addLabel = new JMenuItem("Add " + graphicsType.name());
                addLabel.setActionCommand(graphicsType.name());
                shapeSubMenu.add(addLabel);
                if (SvgUpdateHandler.GraphicsTypes.Polyline.equals(graphicsType)) {
                    addLabel.setEnabled(false);
                }
                addLabel.addActionListener(GraphPanelContextMenu.this);
                // todo: addthese into a layer behind the entities, athought lables could be above
                // todo: when geometry is selected construct an arbildatanode to allow the geometries attributes to be edited
            }
            this.add(shapeSubMenu);

            deleteMenu = new JMenuItem("Delete");
            deleteMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    kinDiagramPanel.showProgressBar();
                    int entityCount = 0;
                    for (UniqueIdentifier uniqueIdentifier : selectedIdentifiers) {
                        if (!uniqueIdentifier.isGraphicsIdentifier() && !uniqueIdentifier.isTransientIdentifier()) {
                            entityCount++;
                        }
                    }
                    boolean doDelete = false;
                    if (entityCount == 0) {
                        doDelete = true;
                    } else if (JOptionPane.OK_OPTION == arbilWindowManager.showDialogBox(entityCount + " entities will be deleted from the database", "Delete Entity", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
                        doDelete = true;
                    }
                    if (doDelete) {
                        ArrayList<UniqueIdentifier> affectedIdentifiers = new ArrayList<UniqueIdentifier>();
                        for (UniqueIdentifier uniqueIdentifier : selectedIdentifiers) {
                            if (uniqueIdentifier.isGraphicsIdentifier()) {
                                graphPanel.svgUpdateHandler.deleteGraphics(uniqueIdentifier);
                            } else if (uniqueIdentifier.isTransientIdentifier()) {
                                kinDiagramPanel.clearProgressBar();
                                throw new UnsupportedOperationException("Cannot delete transient entities.");
                            } else {
                                affectedIdentifiers.add(uniqueIdentifier);
                            }
                        }
                        final UniqueIdentifier[] affectedIdentifiersArray = affectedIdentifiers.toArray(new UniqueIdentifier[]{});
                        try {
                            final RelationLinker relationLinker = new RelationLinker(sessionStorage, arbilWindowManager, entityCollection);
                            relationLinker.deleteEntity(affectedIdentifiersArray);
                        } catch (ImportException exception) {
                            arbilWindowManager.addMessageDialogToQueue("Failed to delete: " + exception.getMessage(), mergeEntitiesMenu.getText());
                        }
                        kinDiagramPanel.removeRequiredNodes(affectedIdentifiersArray);
                        kinDiagramPanel.removeEgoNodes(affectedIdentifiersArray);
                    }
                    kinDiagramPanel.clearProgressBar();
                }
            });
            this.add(deleteMenu);

            mergeEntitiesMenu = new JMenuItem("Merge Selected Entities");
            mergeEntitiesMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    String messageString = "The selected entites will be merged,\nAll relations will be preserved and " + (selectedIdentifiers.length - 1) + " entities will be deleted.\nOnly the data of the initialy selected entity will be kept:\n\"";
                    for (String labelString : graphPanel.getEntityForElementId(selectedIdentifiers[0]).getLabel()) {
                        messageString = messageString + labelString;
                    }
                    messageString = messageString + "\"\nDo you wish to continue?";
                    if (JOptionPane.OK_OPTION == arbilWindowManager.showDialogBox(messageString, "Merge Entities", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {

                        kinDiagramPanel.showProgressBar();
                        try {
                            final EntityMerger entityMerger = new EntityMerger(sessionStorage, arbilWindowManager, entityCollection);
                            entityMerger.mergeEntities(selectedIdentifiers);
                            kinDiagramPanel.entityRelationsChanged(entityMerger.getAffectedIdentifiersArray());
                            kinDiagramPanel.removeRequiredNodes(entityMerger.getDeletedIdentifiersArray());
                        } catch (ImportException exception) {
                            arbilWindowManager.addMessageDialogToQueue("Failed to merge: " + exception.getMessage(), mergeEntitiesMenu.getText());
                        }
                        kinDiagramPanel.clearProgressBar();
                    }
                }
            });
            this.add(mergeEntitiesMenu);

            duplicateEntitiesMenu = new JMenuItem("Duplicate Selected Entities");
            duplicateEntitiesMenu.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    kinDiagramPanel.showProgressBar();
                    try {
                        final UniqueIdentifier[] duplicateEntities = new EntityMerger(sessionStorage, arbilWindowManager, entityCollection).duplicateEntities(selectedIdentifiers);
                        kinDiagramPanel.entityRelationsChanged(selectedIdentifiers);
                        kinDiagramPanel.addRequiredNodes(duplicateEntities);
                    } catch (ImportException exception) {
                        arbilWindowManager.addMessageDialogToQueue("Failed to duplicate: " + exception.getMessage(), duplicateEntitiesMenu.getText());
                    }
                    kinDiagramPanel.clearProgressBar();
                }
            });
            this.add(duplicateEntitiesMenu);

            addRelationEntityMenu = new JMenu("Add Relation");
            this.add(addRelationEntityMenu);
            for (RelationType relationType : RelationType.values()) {
                JMenuItem addRelationEntityMenuItem = new JMenuItem(relationType.name());
                addRelationEntityMenuItem.setActionCommand(relationType.name());
                addRelationEntityMenuItem.addActionListener(new java.awt.event.ActionListener() {

{'fraction_non_alphanumeric': 0.07152716777512862, 'fraction_numerical': 0.002091437654243527, 'mean_word_length': 2.0896872576893255, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '828945', 'n_tokens_mistral': 5582, 'n_tokens_neox': 5344, 'n_words': 1100}