Dépôt officiel du code source de l'ERP OpenConcerto
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);
}
}
}