<commit_before>package de.redsix.pdfcompare.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;

import de.redsix.pdfcompare.CompareResultWithExpectedAndActual;
import de.redsix.pdfcompare.Exclusions;
import de.redsix.pdfcompare.PageArea;
import de.redsix.pdfcompare.env.DefaultEnvironment;
import de.redsix.pdfcompare.env.Environment;


public class ExclusionsPanel extends JPanel {
    
    private Environment environment;
    private JPanel exclusionsList;
    private JLabel configFile;
    /** currently selected file or directory for exports */
    private File selectedFile;
    /** original differences between PDF files for reference */
    private CompareResultWithExpectedAndActual compareResult;
    private ExclusionItemPanel selectedItem;
    private Display display;
    
    
    public ExclusionsPanel(Display display) {
        // FIXME: unsure what the role of the environment is
        environment = DefaultEnvironment.create();
        this.display = display;
        
        init();
    }
    
    private void init() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(220, 100));
        
        this.add(new JLabel("Excluded Areas"), BorderLayout.NORTH);
        
        exclusionsList = new JPanel();
        exclusionsList.setLayout(new BoxLayout(exclusionsList, BoxLayout.PAGE_AXIS));
        
        JPanel configPanel = new JPanel(null);
        configPanel.setPreferredSize(new Dimension(200, 40));
        JLabel configLabel = new JLabel("Config File:");
        configLabel.setFont(Font.decode("SansSerif-plain-10"));
        configLabel.setBounds(5, 0, 190, 15);
        configPanel.add(configLabel);
        
        configFile = new JLabel("unknown");
        configFile.setBounds(10, 15, 190, 20);
        configPanel.add(configFile);
        
        JPanel exclusionsWrapper = new JPanel(new BorderLayout());
        exclusionsWrapper.add(exclusionsList, BorderLayout.NORTH);
        exclusionsWrapper.add(configPanel, BorderLayout.SOUTH);
        
        JScrollPane scrollPane = new JScrollPane(exclusionsWrapper);
        this.add(scrollPane, BorderLayout.CENTER);
        
        JToolBar toolBar = new JToolBar();
        toolBar.setRollover(true);
        toolBar.setFloatable(false);
        this.add(toolBar, BorderLayout.SOUTH);
        
        addToolBarButton(toolBar, "New", "Add new exclusion block", event -> addItemAction());
        addToolBarButton(toolBar, "Diffs", "Show computed differences", event -> useDifferencesAction());
        addToolBarButton(toolBar, "Load", "Load exclusions file", event -> loadAction());
        addToolBarButton(toolBar, "Save", "Save exclusions file", event -> saveAction());        
        
        // support to drag config files into the panel
        new DropTarget(this, DnDConstants.ACTION_COPY, new DropTargetAdapter() {
            
            @Override
            public void drop(DropTargetDropEvent dtde) {
                DataFlavor flavor = DataFlavor.javaFileListFlavor;
                
                if (! dtde.isDataFlavorSupported(flavor) ) {
                    dtde.rejectDrop();
                    return;
                }
                
                try {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY);
                    List<File> files = (List<File>) dtde.getTransferable().getTransferData(flavor);
                    if (files == null || files.isEmpty()) {
                        dtde.dropComplete(false);
                        return;
                    }
                    
                    
                    File exclusionFile = files.get(0);
                    openExclusionFile(exclusionFile);
                    
                    dtde.dropComplete(true);
                    
                } catch (Exception e) {
                    dtde.dropComplete(false);
                }
            }
            
            @Override
            public void dragEnter(DropTargetDragEvent dtde) {
                if (! dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) {
                    dtde.rejectDrag();
                    return;
                }
                
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
                
            }
            
            @Override
            public void dragOver(DropTargetDragEvent dtde) {
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
            }
            
            @Override
            public void dropActionChanged(DropTargetDragEvent dtde) {
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
            }
            
        });
    }
    
    private void addItemAction() {
        addExclusion(new PageArea(display.getPageNumber()));
    }
    
    private void useDifferencesAction() {
        useCompareResults();
        display.redrawImages();
    }
    
    private void loadAction() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(selectedFile);
        
        if (fileChooser.showDialog(this, "Open exclusions definition") == JFileChooser.APPROVE_OPTION) {
            openExclusionFile(fileChooser.getSelectedFile());
        }
    }
    
    private void saveAction() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(selectedFile);
        if (fileChooser.showDialog(this, "Save exclusions as") == JFileChooser.APPROVE_OPTION) {
            try {
                selectedFile = fileChooser.getSelectedFile();
                
                saveExclusionFile(selectedFile);
            } catch (IOException ex) {
                JFrame frame = getFrame(this);
                Display.DisplayExceptionDialog(frame, ex);
            }<commit_msg>Security question for computing differences<commit_after>package de.redsix.pdfcompare.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;

import de.redsix.pdfcompare.CompareResultWithExpectedAndActual;
import de.redsix.pdfcompare.Exclusions;
import de.redsix.pdfcompare.PageArea;
import de.redsix.pdfcompare.env.DefaultEnvironment;
import de.redsix.pdfcompare.env.Environment;


public class ExclusionsPanel extends JPanel {
    
    private Environment environment;
    private JPanel exclusionsList;
    private JLabel configFile;
    /** currently selected file or directory for exports */
    private File selectedFile;
    /** original differences between PDF files for reference */
    private CompareResultWithExpectedAndActual compareResult;
    private ExclusionItemPanel selectedItem;
    private Display display;
    
    
    public ExclusionsPanel(Display display) {
        // FIXME: unsure what the role of the environment is
        environment = DefaultEnvironment.create();
        this.display = display;
        
        init();
    }
    
    private void init() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(220, 100));
        
        this.add(new JLabel("Excluded Areas"), BorderLayout.NORTH);
        
        exclusionsList = new JPanel();
        exclusionsList.setLayout(new BoxLayout(exclusionsList, BoxLayout.PAGE_AXIS));
        
        JPanel configPanel = new JPanel(null);
        configPanel.setPreferredSize(new Dimension(200, 40));
        JLabel configLabel = new JLabel("Config File:");
        configLabel.setFont(Font.decode("SansSerif-plain-10"));
        configLabel.setBounds(5, 0, 190, 15);
        configPanel.add(configLabel);
        
        configFile = new JLabel("unknown");
        configFile.setBounds(10, 15, 190, 20);
        configPanel.add(configFile);
        
        JPanel exclusionsWrapper = new JPanel(new BorderLayout());
        exclusionsWrapper.add(exclusionsList, BorderLayout.NORTH);
        exclusionsWrapper.add(configPanel, BorderLayout.SOUTH);
        
        JScrollPane scrollPane = new JScrollPane(exclusionsWrapper);
        this.add(scrollPane, BorderLayout.CENTER);
        
        JToolBar toolBar = new JToolBar();
        toolBar.setRollover(true);
        toolBar.setFloatable(false);
        this.add(toolBar, BorderLayout.SOUTH);
        
        addToolBarButton(toolBar, "New", "Add new exclusion block", event -> addItemAction());
        addToolBarButton(toolBar, "Diffs", "Show computed differences", event -> showComputedDifferencesAction());
        addToolBarButton(toolBar, "Load", "Load exclusions file", event -> loadAction());
        addToolBarButton(toolBar, "Save", "Save exclusions file", event -> saveAction());        
        
        // support to drag config files into the panel
        new DropTarget(this, DnDConstants.ACTION_COPY, new DropTargetAdapter() {
            
            @Override
            public void drop(DropTargetDropEvent dtde) {
                DataFlavor flavor = DataFlavor.javaFileListFlavor;
                
                if (! dtde.isDataFlavorSupported(flavor) ) {
                    dtde.rejectDrop();
                    return;
                }
                
                try {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY);
                    @SuppressWarnings("unchecked")
                    List<File> files = (List<File>) dtde.getTransferable().getTransferData(flavor);
                    if (files == null || files.isEmpty()) {
                        dtde.dropComplete(false);
                        return;
                    }
                    
                    
                    File exclusionFile = files.get(0);
                    openExclusionFile(exclusionFile);
                    
                    dtde.dropComplete(true);
                    
                } catch (Exception e) {
                    dtde.dropComplete(false);
                }
            }
            
            @Override
            public void dragEnter(DropTargetDragEvent dtde) {
                if (! dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) {
                    dtde.rejectDrag();
                    return;
                }
                
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
                
            }
            
            @Override
            public void dragOver(DropTargetDragEvent dtde) {
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
            }
            
            @Override
            public void dropActionChanged(DropTargetDragEvent dtde) {
                if (dtde.getDropAction() != DnDConstants.ACTION_COPY) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                }
            }
            
        });
    }
    
    private void addItemAction() {
        addExclusion(new PageArea(display.getPageNumber()));
    }
    
    private void showComputedDifferencesAction() {
        if (exclusionsList.getComponents().length == 0 || askForReplacement()) {
            useCompareResults();
            display.redrawImages();
        }
    }

    private boolean askForReplacement() {
        return JOptionPane.showConfirmDialog(null, "This replaces the current exclusions with the computed differences.", "Info",
                JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION;
    }
    
    private void loadAction() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(selectedFile);
        
        if (fileChooser.showDialog(this, "Open exclusions definition") == JFileChooser.APPROVE_OPTION) {
            openExclusionFile(fileChooser.getSelectedFile());
        }
    }
    
    private void saveAction() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(selectedFile);
        if (fileChooser.showDialog(this, "Save exclusions as") == JFileChooser.APPROVE_OPTION) {
            try {
                selectedFile = fileChooser.getSelectedFile();
                
                saveExclusionFile(selectedFile);
            } catch (IOException ex) {
                JFrame frame = getFrame(this);
                Display.DisplayExceptionDialog(frame, ex);
            }
{'fraction_non_alphanumeric': 0.09034311012728279, 'fraction_numerical': 0.0042197011621472056, 'mean_word_length': 2.1231367465975373, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, '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': '6269666', 'n_tokens_mistral': 3998, 'n_tokens_neox': 3781, 'n_words': 739}