OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 151 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.core.edm;

import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.JImage;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;

public class FilePanel extends JPanel {
    private static final Color HOVER_COLOR = new Color(230, 240, 255);
    private static final Color SELECTED_COLOR = new Color(193, 220, 252);

    public static final int PREFERRED_WIDTH = 128;
    public static final int PREFERRED_HEIGHT = 74;

    private final JLabel label;
    private JImage image;
    private AttachmentPanel attachmentPanel;
    private Attachment attachment;

    public FilePanel(final Attachment attachment, final AttachmentPanel panelSource) {
        this.attachment = attachment;
        this.attachmentPanel = panelSource;
        final String name = attachment.getName();
        this.setOpaque(true);
        this.setLayout(new BorderLayout());
        try {
            String type = attachment.getMimeType();
            if (type == null || type.trim().isEmpty() || type.equals("application/octet-stream")) {
                image = new JImage(this.getClass().getResource("data-icon.png"));
            } else if (type.equals("application/msword")) {
                image = new JImage(this.getClass().getResource("doc-icon.png"));
            } else if (type.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
                image = new JImage(this.getClass().getResource("docx-icon.png"));
            } else if (type.equals("application/vnd.oasis.opendocument.text")) {
                image = new JImage(this.getClass().getResource("odt-icon.png"));
            } else if (type.equals("application/pdf")) {
                image = new JImage(this.getClass().getResource("pdf-icon.png"));
            } else if (type.equals("image/jpeg")) {
                image = new JImage(this.getClass().getResource("jpg-icon.png"));
            } else if (type.equals("image/png")) {
                image = new JImage(this.getClass().getResource("png-icon.png"));
            } else if (type.equals("application/vnd.oasis.opendocument.spreadsheet")) {
                image = new JImage(this.getClass().getResource("ods-icon.png"));
            } else if (type.equals("application/msexcel") || type.equals("application/vnd.ms-excel") || type.equals("application/xls")) {
                image = new JImage(this.getClass().getResource("xls-icon.png"));
            } else if (type.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
                image = new JImage(this.getClass().getResource("xlsx-icon.png"));
            } else if (type.equals(Attachment.MIMETYPE_FOLDER)) {
                image = new JImage(this.getClass().getResource("folder-icon.png"));
            } else if (type.equals(Attachment.MIMETYPE_URL) || type.equals("application/x-mswinurl")) {
                image = new JImage(this.getClass().getResource("url-icon.png"));
            } else {
                image = new JImage(this.getClass().getResource("data-icon.png"));
            }
            image.setOpaque(true);
            image.setCenterImage(true);
            this.add(image, BorderLayout.CENTER);
        } catch (Exception e) {
            ExceptionHandler.handle("image error", e);
        }
        setBackground(Color.WHITE);
        label = new JLabel(name, SwingConstants.CENTER);
        label.setOpaque(false);
        label.setPreferredSize(new Dimension(label.getPreferredSize().width, new JTextField("a").getPreferredSize().height));
        this.add(label, BorderLayout.SOUTH);
        int fontSize = label.getFont().getSize();
        this.setPreferredSize(new Dimension(10 * fontSize, PREFERRED_HEIGHT));
        this.setMinimumSize(new Dimension(10 * fontSize, PREFERRED_HEIGHT));
        updateBackgroundFromState();
        this.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                final JComponent lab = (JComponent) e.getSource();
                final TransferHandler handle = lab.getTransferHandler();
                handle.exportAsDrag(lab, e, TransferHandler.MOVE);
            }
        });
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseExited(MouseEvent e) {
                updateBackgroundFromState();
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                if (panelSource.isSelected(attachment)) {
                    setBackground(SELECTED_COLOR);
                } else {
                    setBackground(HOVER_COLOR);
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
                final boolean ctrlPressed = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
                if (!ctrlPressed) {
                    panelSource.select(attachment);
                    updateBackgroundFromState();
                } else {
                    if (!panelSource.isSelected(FilePanel.this.attachment)) {
                        // Add to selection if selected
                        panelSource.select(attachment);
                    } else {
                        panelSource.deselect(attachment);
                    }
                    updateBackgroundFromState();
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                final boolean ctrlPressed = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
                if (!ctrlPressed) {
                    panelSource.clearSelection();
                    panelSource.select(attachment);
                    panelSource.updatePanels();
                }
            }
        });
        initMenu(attachment, panelSource, name);

        this.setTransferHandler(new TransferHandler("id") {

            @SuppressWarnings("unchecked")
            @Override
            public boolean canImport(TransferSupport support) {
                if (!attachment.isFolder())
                    return false;
                try {
                    final List<Attachment> attachmentsToImport = (List<Attachment>) support.getTransferable().getTransferData(support.getDataFlavors()[0]);
                    for (Attachment a : attachmentsToImport) {
                        if (a.getId() == attachment.getId()) {
                            return false;
                        }
                    }
                } catch (UnsupportedFlavorException | IOException e) {
                    e.printStackTrace();
                }
                return true;
            }

            @Override
            public boolean importData(TransferSupport support) {
                if (!canImport(support)) {
                    return false;
                }
                try {
                    @SuppressWarnings("unchecked")
                    final List<Attachment> attachmentsToImport = (List<Attachment>) support.getTransferable().getTransferData(support.getDataFlavors()[0]);
                    final AttachmentUtils utils = new AttachmentUtils();
                    for (Attachment a : attachmentsToImport) {
                        utils.move(a, attachment);
                    }
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            panelSource.initUI();

                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return true;
            }

            @Override
            protected java.awt.datatransfer.Transferable createTransferable(JComponent c) {
                return new AttachmentTransferable(new ArrayList<>(attachmentPanel.getSelectedAttachments()));
            }

            @Override
            public int getSourceActions(JComponent c) {
                return MOVE;
            }

        }

        );

    }

    public void updateBackgroundFromState() {
        if (this.attachmentPanel.isSelected(this.attachment)) {
            setBackground(SELECTED_COLOR);
        } else {
            setBackground(Color.WHITE);
        }
    }

    private void initMenu(final Attachment attachment, final AttachmentPanel panelSource, final String name) {
        final JPopupMenu menu = new JPopupMenu();
        final JMenuItem menuItemDelete = new JMenuItem("Supprimer");
        menuItemDelete.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int value = 0;
                if (attachment.isFolder()) {
                    value = JOptionPane.showConfirmDialog(FilePanel.this, "Voulez-vous vraiment supprimer ce dossier ?\n" + attachment.getName(), "Supprimer le dossier", JOptionPane.YES_NO_OPTION);
                } else {
                    value = JOptionPane.showConfirmDialog(FilePanel.this,
                            "Voulez-vous vraiment supprimer ce fichier ?\n" + attachment.getName() + "\nFichier original : " + attachment.getFileName() + "\nType : " + attachment.getMimeType(),
                            "Supprimer le fichier", JOptionPane.YES_NO_OPTION);
                }
                if (value == JOptionPane.YES_OPTION) {
                    AttachmentUtils utils = new AttachmentUtils();
                    try {
                        utils.deleteFile(attachment);
                        panelSource.initUI();
                    } catch (Exception e1) {
                        ExceptionHandler.handle("Erreur lors de la suppression", e1);
                    }
                }

            }
        });
        menu.add(menuItemDelete);
        final JMenuItem menuItemRename = new JMenuItem("Renommer");
        menuItemRename.addActionListener(new ActionListener() {

            final JTextField text = new JTextField(name);

            private void stopNameEditing() {
                FilePanel.this.invalidate();
                FilePanel.this.remove(text);
                FilePanel.this.add(label, BorderLayout.SOUTH);
                FilePanel.this.validate();
                FilePanel.this.repaint();
            }

            public void validText(final Attachment attachment, final String name, final JTextField text) {
                try {
                    String newName = text.getText();
                    if (newName.trim().isEmpty()) {
                        newName = name;
                    }
                    AttachmentUtils.rename(attachment, newName);
                    label.setText(newName);
                } catch (Exception e1) {
                    ExceptionHandler.handle("Erreur lors du renommage du fichier!", e1);
                }
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                final String name = attachment.getName();

                text.addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                            validText(attachment, name, text);
                            stopNameEditing();
                        } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                            stopNameEditing();
                        }
                    }

                });
                text.addFocusListener(new FocusListener() {

                    @Override
                    public void focusLost(FocusEvent e) {
                        validText(attachment, name, text);
                        stopNameEditing();
                    }

                    @Override
                    public void focusGained(FocusEvent e) {
                        // Nothing to do here
                    }

                });
                text.addMouseListener(new MouseAdapter() {

                    @Override
                    public void mouseExited(MouseEvent e) {
                        validText(attachment, name, text);
                        stopNameEditing();
                    }

                });

                FilePanel.this.invalidate();
                FilePanel.this.remove(label);
                FilePanel.this.add(text, BorderLayout.SOUTH);
                FilePanel.this.validate();
                FilePanel.this.repaint();

                text.grabFocus();
                text.setSelectionStart(0);
                text.setSelectionEnd(name.length());
            }

        });
        menu.add(menuItemRename);
        if (!attachment.isFolder()) {
            menu.addSeparator();
            JMenuItem menuItemProperties = new JMenuItem("Propriétés");
            menuItemProperties.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    JFrame f = new JFrame();
                    f.setTitle("Propriétés de " + attachment.getName());
                    JPanel p = new JPanel();
                    p.setLayout(new GridBagLayout());
                    GridBagConstraints c = new DefaultGridBagConstraints();
                    // Name
                    c.weightx = 0;
                    p.add(new JLabel("Nom : ", SwingConstants.RIGHT), c);
                    c.gridx++;
                    c.weightx = 1;
                    p.add(new JLabel(attachment.getName()), c);
                    c.gridy++;
                    // Type
                    c.gridx = 0;
                    c.weightx = 0;
                    p.add(new JLabel("Type : ", SwingConstants.RIGHT), c);
                    c.gridx++;
                    c.weightx = 1;
                    p.add(new JLabel(attachment.getMimeType()), c);
                    c.gridy++;
                    // FileName
                    c.gridx = 0;
                    c.weightx = 0;
                    if (attachment.getMimeType().equals(Attachment.MIMETYPE_URL)) {
                        p.add(new JLabel("URL : ", SwingConstants.RIGHT), c);
                    } else {
                        p.add(new JLabel("Fichier original : ", SwingConstants.RIGHT), c);
                    }
                    c.gridx++;
                    c.weightx = 1;
                    p.add(new JLabel(attachment.getFileName()), c);
                    c.gridy++;
                    // Size
                    if (!attachment.getMimeType().equals(Attachment.MIMETYPE_URL)) {
                        c.gridx = 0;
                        c.weightx = 0;
                        p.add(new JLabel("Taille : ", SwingConstants.RIGHT), c);
                        c.gridx++;
                        c.weightx = 1;
                        p.add(new JLabel(attachment.getFileSize() + " octets"), c);
                    }
                    // Spacer
                    c.gridx = 1;
                    c.gridy++;
                    c.weightx = 1;
                    JPanel spacer = new JPanel();
                    spacer.setPreferredSize(new Dimension(300, 1));
                    p.add(spacer, c);
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

                    f.setContentPane(p);
                    f.pack();
                    f.setResizable(false);
                    f.setLocationRelativeTo(FilePanel.this);
                    f.setVisible(true);

                }
            });
            menu.add(menuItemProperties);
        }
        setComponentPopupMenu(menu);
    }

    @Override
    public void setBackground(Color bg) {
        super.setBackground(bg);
        if (image != null) {
            image.setBackground(bg);
        }
    }
}