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

import java.awt.BorderLayout;
import java.io.File;
import java.net.URI;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import nl.mpi.arbil.ArbilIcons;
import nl.mpi.arbil.ui.ArbilWindowManager;
import nl.mpi.arbil.util.ApplicationVersionManager;
import nl.mpi.kinnate.KinOathVersion;
import nl.mpi.kinnate.KinTermSavePanel;
import nl.mpi.kinnate.SavePanel;
import nl.mpi.kinnate.export.ExportToR;
import nl.mpi.kinnate.transcoder.DiagramTranscoder;

/*
 *  Document   : MainFrame
 *  Author     : <NAME>
 *  Created on : Aug 16, 2010, 5:20:20 PM
 */
public class MainFrame extends javax.swing.JFrame {

    private RecentFileMenu recentFileMenu;
    private EntityUploadPanel entityUploadPanel;

    /** Creates new form MainFrame */
    public MainFrame() {
        recentFileMenu = new RecentFileMenu(this);
        initComponents();
        ((EditMenu) editMenu).enableMenuKeys();
        final ApplicationVersionManager versionManager = new ApplicationVersionManager(new KinOathVersion());
        nl.mpi.kinnate.KinnateArbilInjector.injectHandlers(versionManager);
        this.add(jTabbedPane1, BorderLayout.CENTER);
        newDiagramMenuItemActionPerformed(null);

        jMenuBar1.add(new DiagramPanelsMenu(this));
        jMenuBar1.add(new KinTermsMenu(this)); // the main frame is stored in the kin term menu for later use
        jMenuBar1.add(new ArchiveMenu(this));
        this.doLayout();
        this.pack();
        ArbilWindowManager.getSingleInstance().setMessagesCanBeShown(true);
        setTitle(versionManager.getApplicationVersion().applicationTitle + " " + versionManager.getApplicationVersion().compileDate);
        // set the icon for the application (if this is still required for the various OSs). This is not required for Mac but might be needed for windows or linux.
        setIconImage(ArbilIcons.getSingleInstance().linorgIcon.getImage());
//	if (arbilMenuBar.checkNewVersionAtStartCheckBoxMenuItem.isSelected()) {
        // todo: Ticket #1066 add the check for updates and check now menu items
        versionManager.checkForUpdate();
//	}
    }

    private SavePanel getSavePanel(int tabIndex) {
        Object selectedComponent = jTabbedPane1.getComponentAt(tabIndex);
        SavePanel savePanel = null;
        if (selectedComponent instanceof SavePanel) {
            savePanel = (SavePanel) selectedComponent;
        }
        return savePanel;
    }

    public KinTermSavePanel getKinTermPanel() {
        Object selectedComponent = jTabbedPane1.getComponentAt(jTabbedPane1.getSelectedIndex());
        KinTermSavePanel kinTermSavePanel = null;
        if (selectedComponent instanceof KinTermSavePanel) {
            kinTermSavePanel = (KinTermSavePanel) selectedComponent;
        }
        return kinTermSavePanel;
    }

    public void openDiagram(String diagramTitle, URI selectedUri, boolean saveToRecentMenu) {
        if (saveToRecentMenu) {
            // prevent files from the samples menu being added to the recent files menu
            recentFileMenu.addRecentFile(new File(selectedUri));
        }
        KinDiagramPanel egoSelectionTestPanel = new KinDiagramPanel(selectedUri, saveToRecentMenu);
//        egoSelectionTestPanel.setTransferHandler(dragTransferHandler);
        jTabbedPane1.add(diagramTitle, egoSelectionTestPanel);
        jTabbedPane1.setSelectedComponent(egoSelectionTestPanel);
//        egoSelectionTestPanel.drawGraph();
    }

    public void importEntities(String importPath) {
        new GedcomImportPanel(jTabbedPane1).startImportJar(importPath);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        ImportGedcomUrl = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        newDiagramMenuItem = new javax.swing.JMenuItem();
        jMenu3 = new nl.mpi.kinnate.ui.DocumentNewMenu(jTabbedPane1);
        openDiagram = new javax.swing.JMenuItem();
        openRecentMenu = recentFileMenu;
        jMenu1 = new SamplesFileMenu(this);
        jMenu2 = new ImportSamplesFileMenu(this);
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        entityUploadMenuItem = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JPopupMenu.Separator();
        saveDiagram = new javax.swing.JMenuItem();
        saveDiagramAs = new javax.swing.JMenuItem();
        savePdfMenuItem = new javax.swing.JMenuItem();
        exportToR = new javax.swing.JMenuItem();
        closeTabMenuItem = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        saveAsDefaultMenuItem = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JPopupMenu.Separator();
        exitApplication = new javax.swing.JMenuItem();
        editMenu = new EditMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().add(jTabbedPane1, java.awt.BorderLayout.PAGE_START);

        fileMenu.setText("File");
        fileMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                fileMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
        });
        fileMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fileMenuActionPerformed(evt);
            }
        });

        ImportGedcomUrl.setText("Import Gedcom Samples (from internet)");
        ImportGedcomUrl.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ImportGedcomUrlActionPerformed(evt);
            }
        });
        fileMenu.add(ImportGedcomUrl);
        fileMenu.add(jSeparator1);

        newDiagramMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        newDiagramMenuItem.setText("New (default diagram)");
        newDiagramMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newDiagramMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(newDiagramMenuItem);

        jMenu3.setText("New Diagram of Type");
        fileMenu.add(jMenu3);

        openDiagram.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        openDiagram.setText("Open");
        openDiagram.setActionCommand("open");
        openDiagram.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openDiagramActionPerformed(evt);
            }
        });
        fileMenu.add(openDiagram);

        openRecentMenu.setText("Open Recent Diagram");
        openRecentMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openRecentMenuActionPerformed(evt);
            }
        });
        fileMenu.add(openRecentMenu);

        jMenu1.setText("Open Sample Diagram");
        fileMenu.add(jMenu1);

        jMenu2.setText("Import Sample Data");
        fileMenu.add(jMenu2);
        fileMenu.add(jSeparator2);

        entityUploadMenuItem.setText("Entity Upload");
        entityUploadMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entityUploadMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(entityUploadMenuItem);
        fileMenu.add(jSeparator4);

        saveDiagram.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        saveDiagram.setText("Save");
        saveDiagram.setActionCommand("save");
        saveDiagram.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveDiagramActionPerformed(evt);
            }
        });
        fileMenu.add(saveDiagram);

        saveDiagramAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        saveDiagramAs.setText("Save As");
        saveDiagramAs.setActionCommand("saveas");
        saveDiagramAs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveDiagramAsActionPerformed(evt);
            }
        });
        fileMenu.add(saveDiagramAs);

        savePdfMenuItem.setText("Export as PDF");
        savePdfMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                savePdfMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(savePdfMenuItem);

        exportToR.setText("Export to R / SPSS");
        exportToR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportToRActionPerformed(evt);
            }
        });
        fileMenu.add(exportToR);

        closeTabMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.CTRL_MASK));
        closeTabMenuItem.setText("Close");
        closeTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeTabMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(closeTabMenuItem);
        fileMenu.add(jSeparator3);

        saveAsDefaultMenuItem.setText("Save as Default Diagram");
        saveAsDefaultMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveAsDefaultMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveAsDefaultMenuItem);
        fileMenu.add(jSeparator5);

        exitApplication.setText("Exit");
        exitApplication.setActionCommand("exit");
        exitApplication.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitApplicationActionPerformed(evt);
            }
        });
        fileMenu.add(exitApplication);

        jMenuBar1.add(fileMenu);

        editMenu.setText("Edit");
        editMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                editMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
        });
        editMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editMenuActionPerformed(evt);
            }
        });
        jMenuBar1.add(editMenu);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void fileMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileMenuActionPerformed
    }//GEN-LAST:event_fileMenuActionPerformed

    private void openDiagramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openDiagramActionPerformed
        final File[] selectedFilesArray = ArbilWindowManager.getSingleInstance().showFileSelectBox("Open Kin Diagram", false, true, false);
        if (selectedFilesArray != null) {
            for (File selectedFile : selectedFilesArray) {
                openDiagram(selectedFile.getName(), selectedFile.toURI(), true);
            }
        }
    }//GEN-LAST:event_openDiagramActionPerformed

    private void openRecentMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentMenuActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_openRecentMenuActionPerformed

    private void saveDiagramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDiagramActionPerformed
        int tabIndex = Integer.valueOf(evt.getActionCommand());
        SavePanel savePanel = getSavePanel(tabIndex);
        savePanel.saveToFile();
    }//GEN-LAST:event_saveDiagramActionPerformed

    private void saveDiagramAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDiagramAsActionPerformed
        // todo: update the file select to limit to svg and test that a file has been selected
        // todo: move this into the arbil window manager and get the last used directory
        // todo: make sure the file has the svg suffix
        JFileChooser fc = new JFileChooser();
        fc.addChoosableFileFilter(new FileFilter() {

            @Override
            public boolean accept(File file) {
                if (file.isDirectory()) {
                    return true;
                }
                return (file.getName().toLowerCase().endsWith(".svg"));
            }

            @Override
            public String getDescription() {
                return "Scalable Vector Graphics (SVG)";
            }
        });

        int returnVal = fc.showSaveDialog(this);
        // make sure the file path ends in .svg lowercase
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File svgFile = fc.getSelectedFile();
            if (!svgFile.getName().toLowerCase().endsWith(".svg")) {
                svgFile = new File(svgFile.getParentFile(), svgFile.getName() + ".svg");
            }
            int tabIndex = Integer.valueOf(evt.getActionCommand());
            SavePanel savePanel = getSavePanel(tabIndex);
            savePanel.saveToFile(svgFile);
            recentFileMenu.addRecentFile(svgFile);
            jTabbedPane1.setTitleAt(tabIndex, svgFile.getName());
        } else {
            // todo: warn user that no file selected and so cannot save
        }
//        File selectedFile[] = LinorgWindowManager.getSingleInstance().showFileSelectBox("Save Kin Diagram", false, false, false);
//        if (selectedFile != null && selectedFile.length > 0) {
//            int tabIndex = Integer.valueOf(evt.getActionCommand());
//            SavePanel savePanel = getSavePanel(tabIndex);
//            savePanel.saveToFile(selectedFile[0]);
//            jTabbedPane1.setTitleAt(tabIndex, selectedFile[0].getName());
//        } else {
//            // todo: warn user that no file selected and so cannot save
//        }
    }//GEN-LAST:event_saveDiagramAsActionPerformed

    private void exitApplicationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitApplicationActionPerformed
        // todo: check that things are saved and ask user if not
        System.exit(0);
    }//GEN-LAST:event_exitApplicationActionPerformed

    private void fileMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_fileMenuMenuSelected
        // set the save, save as and close text to include the tab to which the action will occur
        int selectedIndex = jTabbedPane1.getSelectedIndex();
        String currentTabText = jTabbedPane1.getTitleAt(selectedIndex);
        SavePanel savePanel = getSavePanel(selectedIndex);
        saveDiagramAs.setText("Save As (" + currentTabText + ")");
        saveDiagramAs.setActionCommand(Integer.toString(selectedIndex));
        saveDiagram.setText("Save (" + currentTabText + ")");
        saveDiagram.setActionCommand(Integer.toString(selectedIndex));
        closeTabMenuItem.setText("Close (" + currentTabText + ")");
        closeTabMenuItem.setActionCommand(Integer.toString(selectedIndex));
        saveAsDefaultMenuItem.setText("Save (" + currentTabText + ") as Default Diagram");
        saveAsDefaultMenuItem.setActionCommand(Integer.toString(selectedIndex));
        if (savePanel != null) {
            saveDiagram.setEnabled(savePanel.hasSaveFileName() && savePanel.requiresSave());
            saveDiagramAs.setEnabled(true);
            exportToR.setEnabled(true);
            closeTabMenuItem.setEnabled(true);
            saveAsDefaultMenuItem.setEnabled(true);
            savePdfMenuItem.setEnabled(true);
        } else {
            saveDiagramAs.setEnabled(false);
            saveDiagram.setEnabled(false);
            exportToR.setEnabled(false);
            closeTabMenuItem.setEnabled(false);
            saveAsDefaultMenuItem.setEnabled(false);
            savePdfMenuItem.setEnabled(false);
        }
    }//GEN-LAST:event_fileMenuMenuSelected

    private void closeTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeTabMenuItemActionPerformed
        int tabIndex = Integer.valueOf(evt.getActionCommand());
        SavePanel savePanel = getSavePanel(tabIndex);
        if (savePanel.requiresSave()) {
            // todo: warn user to save
        }
        jTabbedPane1.remove(tabIndex);
    }//GEN-LAST:event_closeTabMenuItemActionPerformed

    private void newDiagramMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newDiagramMenuItemActionPerformed<commit_msg>Updated svg samples to accommodate the recent format changes. Reduced debug output. Set the sample name in the diagram title. Updated the sample file open process for the installed versions. Updated the default diagram code to suit the other changes. Made sure the file path ends in .svg lowercase and that any appended suffix is included in the recent file data. Restricted the recent file list to x number so that it does not get out of control. Added a svg hander for messages, errors and link activation events.<commit_after>package nl.mpi.kinnate.ui;

import java.awt.BorderLayout;
import java.io.File;
import java.net.URI;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import nl.mpi.arbil.ArbilIcons;
import nl.mpi.arbil.ui.ArbilWindowManager;
import nl.mpi.arbil.util.ApplicationVersionManager;
import nl.mpi.kinnate.KinOathVersion;
import nl.mpi.kinnate.KinTermSavePanel;
import nl.mpi.kinnate.SavePanel;
import nl.mpi.kinnate.export.ExportToR;
import nl.mpi.kinnate.transcoder.DiagramTranscoder;

/*
 *  Document   : MainFrame
 *  Author     : <NAME>
 *  Created on : Aug 16, 2010, 5:20:20 PM
 */
public class MainFrame extends javax.swing.JFrame {

    private RecentFileMenu recentFileMenu;
    private EntityUploadPanel entityUploadPanel;

    /** Creates new form MainFrame */
    public MainFrame() {
        recentFileMenu = new RecentFileMenu(this);
        initComponents();
        ((EditMenu) editMenu).enableMenuKeys();
        final ApplicationVersionManager versionManager = new ApplicationVersionManager(new KinOathVersion());
        nl.mpi.kinnate.KinnateArbilInjector.injectHandlers(versionManager);
        this.add(jTabbedPane1, BorderLayout.CENTER);
        newDiagramMenuItemActionPerformed(null);

        jMenuBar1.add(new DiagramPanelsMenu(this));
        jMenuBar1.add(new KinTermsMenu(this)); // the main frame is stored in the kin term menu for later use
        jMenuBar1.add(new ArchiveMenu(this));
        this.doLayout();
        this.pack();
        ArbilWindowManager.getSingleInstance().setMessagesCanBeShown(true);
        setTitle(versionManager.getApplicationVersion().applicationTitle + " " + versionManager.getApplicationVersion().compileDate);
        // set the icon for the application (if this is still required for the various OSs). This is not required for Mac but might be needed for windows or linux.
        setIconImage(ArbilIcons.getSingleInstance().linorgIcon.getImage());
//	if (arbilMenuBar.checkNewVersionAtStartCheckBoxMenuItem.isSelected()) {
        // todo: Ticket #1066 add the check for updates and check now menu items
        versionManager.checkForUpdate();
//	}
    }

    private SavePanel getSavePanel(int tabIndex) {
        Object selectedComponent = jTabbedPane1.getComponentAt(tabIndex);
        SavePanel savePanel = null;
        if (selectedComponent instanceof SavePanel) {
            savePanel = (SavePanel) selectedComponent;
        }
        return savePanel;
    }

    public KinTermSavePanel getKinTermPanel() {
        Object selectedComponent = jTabbedPane1.getComponentAt(jTabbedPane1.getSelectedIndex());
        KinTermSavePanel kinTermSavePanel = null;
        if (selectedComponent instanceof KinTermSavePanel) {
            kinTermSavePanel = (KinTermSavePanel) selectedComponent;
        }
        return kinTermSavePanel;
    }

    public void openDiagram(String diagramTitle, URI selectedUri, boolean saveToRecentMenu) {
        if (saveToRecentMenu) {
            // prevent files from the samples menu being added to the recent files menu
            recentFileMenu.addRecentFile(new File(selectedUri));
        }
        KinDiagramPanel egoSelectionTestPanel = new KinDiagramPanel(selectedUri, saveToRecentMenu);
//        egoSelectionTestPanel.setTransferHandler(dragTransferHandler);
        jTabbedPane1.add(diagramTitle, egoSelectionTestPanel);
        jTabbedPane1.setSelectedComponent(egoSelectionTestPanel);
//        egoSelectionTestPanel.drawGraph();
    }

    public void importEntities(String importPath) {
        new GedcomImportPanel(jTabbedPane1).startImportJar(importPath);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        ImportGedcomUrl = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        newDiagramMenuItem = new javax.swing.JMenuItem();
        jMenu3 = new nl.mpi.kinnate.ui.DocumentNewMenu(jTabbedPane1);
        openDiagram = new javax.swing.JMenuItem();
        openRecentMenu = recentFileMenu;
        jMenu1 = new SamplesFileMenu(this);
        jMenu2 = new ImportSamplesFileMenu(this);
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        entityUploadMenuItem = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JPopupMenu.Separator();
        saveDiagram = new javax.swing.JMenuItem();
        saveDiagramAs = new javax.swing.JMenuItem();
        savePdfMenuItem = new javax.swing.JMenuItem();
        exportToR = new javax.swing.JMenuItem();
        closeTabMenuItem = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        saveAsDefaultMenuItem = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JPopupMenu.Separator();
        exitApplication = new javax.swing.JMenuItem();
        editMenu = new EditMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().add(jTabbedPane1, java.awt.BorderLayout.PAGE_START);

        fileMenu.setText("File");
        fileMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                fileMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
        });
        fileMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fileMenuActionPerformed(evt);
            }
        });

        ImportGedcomUrl.setText("Import Gedcom Samples (from internet)");
        ImportGedcomUrl.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ImportGedcomUrlActionPerformed(evt);
            }
        });
        fileMenu.add(ImportGedcomUrl);
        fileMenu.add(jSeparator1);

        newDiagramMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        newDiagramMenuItem.setText("New (default diagram)");
        newDiagramMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newDiagramMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(newDiagramMenuItem);

        jMenu3.setText("New Diagram of Type");
        fileMenu.add(jMenu3);

        openDiagram.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        openDiagram.setText("Open");
        openDiagram.setActionCommand("open");
        openDiagram.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openDiagramActionPerformed(evt);
            }
        });
        fileMenu.add(openDiagram);

        openRecentMenu.setText("Open Recent Diagram");
        openRecentMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openRecentMenuActionPerformed(evt);
            }
        });
        fileMenu.add(openRecentMenu);

        jMenu1.setText("Open Sample Diagram");
        fileMenu.add(jMenu1);

        jMenu2.setText("Import Sample Data");
        fileMenu.add(jMenu2);
        fileMenu.add(jSeparator2);

        entityUploadMenuItem.setText("Entity Upload");
        entityUploadMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entityUploadMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(entityUploadMenuItem);
        fileMenu.add(jSeparator4);

        saveDiagram.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        saveDiagram.setText("Save");
        saveDiagram.setActionCommand("save");
        saveDiagram.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveDiagramActionPerformed(evt);
            }
        });
        fileMenu.add(saveDiagram);

        saveDiagramAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        saveDiagramAs.setText("Save As");
        saveDiagramAs.setActionCommand("saveas");
        saveDiagramAs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveDiagramAsActionPerformed(evt);
            }
        });
        fileMenu.add(saveDiagramAs);

        savePdfMenuItem.setText("Export as PDF");
        savePdfMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                savePdfMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(savePdfMenuItem);

        exportToR.setText("Export to R / SPSS");
        exportToR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportToRActionPerformed(evt);
            }
        });
        fileMenu.add(exportToR);

        closeTabMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.CTRL_MASK));
        closeTabMenuItem.setText("Close");
        closeTabMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeTabMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(closeTabMenuItem);
        fileMenu.add(jSeparator3);

        saveAsDefaultMenuItem.setText("Save as Default Diagram");
        saveAsDefaultMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveAsDefaultMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveAsDefaultMenuItem);
        fileMenu.add(jSeparator5);

        exitApplication.setText("Exit");
        exitApplication.setActionCommand("exit");
        exitApplication.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitApplicationActionPerformed(evt);
            }
        });
        fileMenu.add(exitApplication);

        jMenuBar1.add(fileMenu);

        editMenu.setText("Edit");
        editMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                editMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
        });
        editMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editMenuActionPerformed(evt);
            }
        });
        jMenuBar1.add(editMenu);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void fileMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileMenuActionPerformed
    }//GEN-LAST:event_fileMenuActionPerformed

    private void openDiagramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openDiagramActionPerformed
        final File[] selectedFilesArray = ArbilWindowManager.getSingleInstance().showFileSelectBox("Open Kin Diagram", false, true, false);
        if (selectedFilesArray != null) {
            for (File selectedFile : selectedFilesArray) {
                openDiagram(selectedFile.getName(), selectedFile.toURI(), true);
            }
        }
    }//GEN-LAST:event_openDiagramActionPerformed

    private void openRecentMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentMenuActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_openRecentMenuActionPerformed

    private void saveDiagramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDiagramActionPerformed
        int tabIndex = Integer.valueOf(evt.getActionCommand());
        SavePanel savePanel = getSavePanel(tabIndex);
        savePanel.saveToFile();
    }//GEN-LAST:event_saveDiagramActionPerformed

    private void saveDiagramAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDiagramAsActionPerformed
        // todo: update the file select to limit to svg and test that a file has been selected
        // todo: move this into the arbil window manager and get the last used directory
        // todo: make sure the file has the svg suffix
        JFileChooser fc = new JFileChooser();
        fc.addChoosableFileFilter(new FileFilter() {

            @Override
            public boolean accept(File file) {
                if (file.isDirectory()) {
                    return true;
                }
                return (file.getName().toLowerCase().endsWith(".svg"));
            }

            @Override
            public String getDescription() {
                return "Scalable Vector Graphics (SVG)";
            }
        });

        int returnVal = fc.showSaveDialog(this);
        // make sure the file path ends in .svg lowercase
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File svgFile = fc.getSelectedFile();
            if (!svgFile.getName().toLowerCase().endsWith(".svg")) {
                svgFile = new File(svgFile.getParentFile(), svgFile.getName() + ".svg");
            }
            int tabIndex = Integer.valueOf(evt.getActionCommand());
            SavePanel savePanel = getSavePanel(tabIndex);
            savePanel.saveToFile(svgFile);
            recentFileMenu.addRecentFile(svgFile);
            jTabbedPane1.setTitleAt(tabIndex, svgFile.getName());
        } else {
            // todo: warn user that no file selected and so cannot save
        }
//        File selectedFile[] = LinorgWindowManager.getSingleInstance().showFileSelectBox("Save Kin Diagram", false, false, false);
//        if (selectedFile != null && selectedFile.length > 0) {
//            int tabIndex = Integer.valueOf(evt.getActionCommand());
//            SavePanel savePanel = getSavePanel(tabIndex);
//            savePanel.saveToFile(selectedFile[0]);
//            jTabbedPane1.setTitleAt(tabIndex, selectedFile[0].getName());
//        } else {
//            // todo: warn user that no file selected and so cannot save
//        }
    }//GEN-LAST:event_saveDiagramAsActionPerformed

    private void exitApplicationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitApplicationActionPerformed
        // todo: check that things are saved and ask user if not
        System.exit(0);
    }//GEN-LAST:event_exitApplicationActionPerformed

    private void fileMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_fileMenuMenuSelected
        // set the save, save as and close text to include the tab to which the action will occur
        int selectedIndex = jTabbedPane1.getSelectedIndex();
        String currentTabText = jTabbedPane1.getTitleAt(selectedIndex);
        SavePanel savePanel = getSavePanel(selectedIndex);
        saveDiagramAs.setText("Save As (" + currentTabText + ")");
        saveDiagramAs.setActionCommand(Integer.toString(selectedIndex));
        saveDiagram.setText("Save (" + currentTabText + ")");
        saveDiagram.setActionCommand(Integer.toString(selectedIndex));
        closeTabMenuItem.setText("Close (" + currentTabText + ")");
        closeTabMenuItem.setActionCommand(Integer.toString(selectedIndex));
        saveAsDefaultMenuItem.setText("Set Default Diagram as (" + currentTabText + ")");
        saveAsDefaultMenuItem.setActionCommand(Integer.toString(selectedIndex));
        if (savePanel != null) {
            saveDiagram.setEnabled(savePanel.hasSaveFileName() && savePanel.requiresSave());
            saveDiagramAs.setEnabled(true);
            exportToR.setEnabled(true);
            closeTabMenuItem.setEnabled(true);
            saveAsDefaultMenuItem.setEnabled(true);
            savePdfMenuItem.setEnabled(true);
        } else {
            saveDiagramAs.setEnabled(false);
            saveDiagram.setEnabled(false);
            exportToR.setEnabled(false);
            closeTabMenuItem.setEnabled(false);
            saveAsDefaultMenuItem.setEnabled(false);
            savePdfMenuItem.setEnabled(false);
        }
    }//GEN-LAST:event_fileMenuMenuSelected

    private void closeTabMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeTabMenuItemActionPerformed
        int tabIndex = Integer.valueOf(evt.getActionCommand());
        SavePanel savePanel = getSavePanel(tabIndex);
        if (savePanel.requiresSave()) {
            // todo: warn user to save
        }
        jTabbedPane1.remove(tabIndex);
    }//GEN-LAST:event_closeTabMenuItemActionPerformed

    private void newDiagramMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newDiagramMenuItemActionPerformed
{'fraction_non_alphanumeric': 0.09755831994991425, 'fraction_numerical': 0.0032664616054658793, 'mean_word_length': 2.852558724832215, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2271021', 'n_tokens_mistral': 10085, 'n_tokens_neox': 10035, 'n_words': 1809}