org.icepdf.ri.common.utility.attachment.AttachmentPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icepdf-viewer Show documentation
Show all versions of icepdf-viewer Show documentation
ICEpdf PDF Viewer Reference Implementation (RI)
package org.icepdf.ri.common.utility.attachment;
import org.icepdf.core.pobjects.*;
import org.icepdf.core.util.Library;
import org.icepdf.core.util.Utils;
import org.icepdf.ri.common.SwingController;
import org.icepdf.ri.common.ViewModel;
import org.icepdf.ri.images.Images;
import org.icepdf.ri.viewer.WindowManager;
import javax.swing.*;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.*;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.icepdf.ri.common.utility.attachment.FileTableModel.*;
/**
* AttachmentPanel displays a PDF attachments as defined by the Catalogs names tree's EmbeddedFiles entry.
* The view is pretty straight forward showing properties on all attached files but only allows the opening
* of .pdf files via a double click of a row. However it is possible to save any file by selecting a table
* row and right clicking to expose the context menu for 'Save as..."
*
* @since 6.2
*/
@SuppressWarnings("serial")
public class AttachmentPanel extends JPanel implements MouseListener, ActionListener {
private static final Logger logger =
Logger.getLogger(AttachmentPanel.class.toString());
public static final String PDF_EXTENSION = ".pdf";
private SwingController controller;
private Document currentDocument;
private JTable fileTable;
private FileTableModel fileTableModel;
private JPopupMenu contextMenu;
private JMenuItem saveAsMenuItem;
private HashMap files;
// message bundle for internationalization
private ResourceBundle messageBundle;
public AttachmentPanel(SwingController controller) {
this.controller = controller;
this.setFocusable(true);
this.messageBundle = this.controller.getMessageBundle();
}
private void buildUI() {
fileTableModel = new FileTableModel(messageBundle, files);
fileTable = new JTable(fileTableModel) {
// Implement table cell tool tips.
public String getToolTipText(MouseEvent e) {
String tip = null;
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
int realColumnIndex = convertColumnIndexToModel(colIndex);
if (realColumnIndex == NAME_COLUMN) {
TableModel model = getModel();
tip = (String) model.getValueAt(rowIndex, NAME_COLUMN);
} else if (realColumnIndex == DESCRIPTION_COLUMN) {
TableModel model = getModel();
tip = (String) model.getValueAt(rowIndex, DESCRIPTION_COLUMN);
} else if (realColumnIndex == MODIFIED_COLUMN) {
TableModel model = getModel();
tip = model.getValueAt(rowIndex, MODIFIED_COLUMN).toString();
} else if (realColumnIndex == SIZE_COLUMN) {
TableModel model = getModel();
tip = model.getValueAt(rowIndex, SIZE_COLUMN).toString();
} else if (realColumnIndex == COMPRESSION_COLUMN) {
TableModel model = getModel();
tip = model.getValueAt(rowIndex, COMPRESSION_COLUMN).toString();
} else {
tip = super.getToolTipText(e);
}
return tip;
}
};
fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// try and show all the file name label.
fileTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(225);
fileTable.getColumnModel().getColumn(DESCRIPTION_COLUMN).setPreferredWidth(50);
fileTable.getColumnModel().getColumn(MODIFIED_COLUMN).setPreferredWidth(75);
fileTable.getColumnModel().getColumn(SIZE_COLUMN).setPreferredWidth(75);
fileTable.getColumnModel().getColumn(COMPRESSION_COLUMN).setPreferredWidth(75);
// add double click support for row, so we can load the file if it's pdf.
fileTable.addMouseListener(this);
// right click context menu for save as.
contextMenu = new JPopupMenu();
saveAsMenuItem = new JMenuItem(messageBundle.getString(
"viewer.utilityPane.attachments.menu.saveAs.label"),
new ImageIcon(Images.get("save_a_24.png")));
saveAsMenuItem.addActionListener(this);
contextMenu.add(saveAsMenuItem);
// remove any previous UI components.
this.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(fileTable,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.getVerticalScrollBar().setUnitIncrement(20);
scrollPane.getHorizontalScrollBar().setUnitIncrement(20);
this.add(scrollPane, BorderLayout.CENTER);
}
public void dispose() {
this.removeAll();
}
/**
* Sets the given document as the current and builds the embedded file table is possible.
*
* @param document document to look for attached files and build table based UI from.
*/
public void setDocument(Document document) {
this.currentDocument = document;
this.removeAll();
files = null;
fileTableModel = null;
if (this.currentDocument != null) {
Catalog catalog = document.getCatalog();
// grab each file pair and build out the FileSpecification objects.
if (catalog.getEmbeddedFilesNameTree() != null) {
NameTree embeddedFilesNameTree = catalog.getEmbeddedFilesNameTree();
java.util.List filePairs = embeddedFilesNameTree.getNamesAndValues();
if (filePairs != null) {
Library library = catalog.getLibrary();
// check to see if at least one file is a PDF.
int max = filePairs.size();
files = new HashMap(max / 2);
for (int i = 0; i < max; i += 2) {
// get the name and document for
// file name and file specification pairs.
Object rawFileName = library.getObject(filePairs.get(i));
Object rawFileProperties = library.getObject(filePairs.get(i + 1));
if (rawFileName != null && rawFileName instanceof LiteralStringObject &&
rawFileProperties != null && rawFileProperties instanceof HashMap) {
String fileName = Utils.convertStringObject(library, (LiteralStringObject) rawFileName);
files.put(fileName, new FileSpecification(library, (HashMap) rawFileProperties));
}
}
buildUI();
}
}
}
}
public void actionPerformed(ActionEvent e) {
// show save as dialog and try to save the file stream.
if (e.getSource().equals(saveAsMenuItem)) {
int selectedRow = fileTable.getSelectedRow();
Object value = fileTableModel.getValueAt(selectedRow, DATA_COLUMN);
if (value != null && value instanceof FileSpecification) {
FileSpecification fileSpecification = (FileSpecification) value;
final EmbeddedFileStream embeddedFileStream = fileSpecification.getEmbeddedFileStream();
final String fileName = (String) fileTableModel.getValueAt(selectedRow, NAME_COLUMN);
// already on awt thread but still nice to play by the rules.
Runnable doSwingWork = new Runnable() {
public void run() {
saveFile(fileName, embeddedFileStream);
}
};
SwingUtilities.invokeLater(doSwingWork);
}
}
}
public void mouseClicked(MouseEvent e) {
// try and do double click file opening of PDF documents.
if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
int selectedRow = fileTable.getSelectedRow();
Object value = fileTableModel.getValueAt(selectedRow, DATA_COLUMN);
if (value != null && value instanceof FileSpecification) {
FileSpecification fileSpecification = (FileSpecification) value;
EmbeddedFileStream embeddedFileStream = fileSpecification.getEmbeddedFileStream();
String fileName = (String) fileTableModel.getValueAt(selectedRow, NAME_COLUMN);
// load the file stream if it's PDF.
if (fileName.toLowerCase().endsWith(PDF_EXTENSION)) {
try {
InputStream fileInputStream = embeddedFileStream.getDecodedStreamData();
Document embeddedDocument = new Document();
embeddedDocument.setInputStream(fileInputStream, fileName);
WindowManager.getInstance().newWindow(embeddedDocument, fileName);
} catch (Throwable e1) {
logger.log(Level.WARNING, "Error opening PDF " + fileName, e);
}
}
}
}
if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) {
int row = fileTable.rowAtPoint(e.getPoint());
// if pointer is over a selected row, show popup
if (fileTable.isRowSelected(row)) {
contextMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
/**
* Utility method to save the embedded file stream as a separate file. Any file can be saved not just
* limited to PDF.
*
* @param fileName filename associated with he embedded file stream.
* @param embeddedFileStream embedded file stream data to save. .
*/
private void saveFile(String fileName, EmbeddedFileStream embeddedFileStream) {
// Create and display a file saving dialog
final JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(messageBundle.getString("viewer.dialog.saveAs.title"));
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
// set the directory to our currently set default.
if (ViewModel.getDefaultFile() != null) {
fileChooser.setCurrentDirectory(ViewModel.getDefaultFile());
}
// set the file name.
fileChooser.setSelectedFile(new File(fileName));
// show the dialog
int returnVal = fileChooser.showSaveDialog(controller.getViewerFrame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
if (file.exists()) {
boolean overWrite = org.icepdf.ri.util.Resources.showConfirmDialog(
controller.getViewerFrame(),
messageBundle,
"viewer.utilityPane.attachments.saveAs.replace.title",
"viewer.utilityPane.attachments.saveAs.replace.msg",
fileName);
if (!overWrite) {
// ask again.
saveFile(fileName, embeddedFileStream);
}
}
// save file stream
try {
InputStream inputStream = embeddedFileStream.getDecodedStreamData();
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream buf = new BufferedOutputStream(fileOutputStream, 8192);
byte[] buffer = new byte[8192];
int length;
while ((length = inputStream.read(buffer)) > 0) {
buf.write(buffer, 0, length);
}
buf.flush();
fileOutputStream.flush();
buf.close();
fileOutputStream.close();
inputStream.close();
} catch (MalformedURLException e) {
logger.log(Level.FINE, "Malformed URL Exception ", e);
} catch (IOException e) {
logger.log(Level.FINE, "IO Exception ", e);
}
// save the default directory
ViewModel.setDefaultFile(file);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy