You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2015/05/25 15:30:54 UTC
svn commit: r1681588 - in
/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools: PDFDebugger.java
pdfdebugger/ pdfdebugger/treestatus/ pdfdebugger/treestatus/TreeStatus.java
pdfdebugger/treestatus/TreeStatusPane.java
Author: tilman
Date: Mon May 25 13:30:54 2015
New Revision: 1681588
URL: http://svn.apache.org/r1681588
Log:
PDFBOX-2530: Tree status line show & input feature, as done by Khyrul Bashar in GSoC2015
Added:
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java (with props)
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java (with props)
Modified:
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java?rev=1681588&r1=1681587&r2=1681588&view=diff
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java (original)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java Mon May 25 13:30:54 2015
@@ -16,6 +16,8 @@
*/
package org.apache.pdfbox.tools;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -31,6 +33,7 @@ import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import org.apache.pdfbox.cos.COSBoolean;
@@ -45,6 +48,8 @@ import org.apache.pdfbox.tools.gui.Array
import org.apache.pdfbox.tools.gui.MapEntry;
import org.apache.pdfbox.tools.gui.PDFTreeCellRenderer;
import org.apache.pdfbox.tools.gui.PDFTreeModel;
+import org.apache.pdfbox.tools.pdfdebugger.treestatus.TreeStatus;
+import org.apache.pdfbox.tools.pdfdebugger.treestatus.TreeStatusPane;
import org.apache.pdfbox.tools.util.RecentFiles;
/**
@@ -54,6 +59,8 @@ import org.apache.pdfbox.tools.util.Rece
*/
public class PDFDebugger extends javax.swing.JFrame
{
+ private TreeStatusPane statusPane;
+
private File currentDir=new File(".");
private PDDocument document = null;
private String currentFilePath = null;
@@ -102,7 +109,7 @@ public class PDFDebugger extends javax.s
jTree1.setCellRenderer( new PDFTreeCellRenderer() );
jTree1.setModel( null );
- setTitle("PDFBox - PDF Viewer");
+ setTitle("PDFBox - PDF Debugger");
addWindowListener(new java.awt.event.WindowAdapter()
{
@Override
@@ -136,6 +143,11 @@ public class PDFDebugger extends javax.s
JScrollPane documentScroller = new JScrollPane();
documentScroller.setViewportView( documentPanel );
+ statusPane = new TreeStatusPane(jTree1);
+ statusPane.getPanel().setBorder(new BevelBorder(BevelBorder.RAISED));
+ statusPane.getPanel().setPreferredSize(new Dimension(300, 25));
+ getContentPane().add(statusPane.getPanel(), BorderLayout.PAGE_START);
+
getContentPane().add( jSplitPane1, java.awt.BorderLayout.CENTER );
fileMenu.setText("File");
@@ -403,8 +415,10 @@ public class PDFDebugger extends javax.s
currentFilePath = file.getPath();
recentFiles.removeFile(file.getPath());
parseDocument( file, password );
+ statusPane.updateTreeStatus(new TreeStatus(document.getDocument().getTrailer()));
TreeModel model=new PDFTreeModel(document);
jTree1.setModel(model);
+ jTree1.setSelectionRow(1);
setTitle("PDFBox - " + file.getAbsolutePath());
addRecentFileItems();
}
Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java?rev=1681588&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java Mon May 25 13:30:54 2015
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pdfbox.tools.pdfdebugger.treestatus;
+
+import java.util.ArrayList;
+import javax.swing.tree.TreePath;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.tools.gui.ArrayEntry;
+import org.apache.pdfbox.tools.gui.MapEntry;
+
+/**
+ * @author Khyrul Bashar
+ */
+public final class TreeStatus
+{
+ private TreePath path;
+ private String pathString;
+ private Object rootNode;
+ public boolean isValid = false;
+
+ private TreeStatus()
+ {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param rootNode the root node of the tree which will be used to construct a treepath from a
+ * tree status string.
+ */
+ public TreeStatus(Object rootNode)
+ {
+ this.rootNode = rootNode;
+ }
+
+ /**
+ * Return the treepath.
+ * @return the treepath.
+ */
+ public TreePath getPath()
+ {
+ return path;
+ }
+
+ /**
+ * Set the path and generate corresponding tree status string.
+ * @param path TreePath instance.
+ */
+ public void setPath(TreePath path)
+ {
+ this.path = path;
+ this.pathString = generatePathString(path);
+ this.isValid = true;
+ }
+
+ /**
+ * Set the tree status string and try to generate TreePath. In case of success, the path will be
+ * available for further uses. In case of failure path will be set to null.
+ *
+ * @param pathString String instance.
+ */
+ public void setPathString(String pathString)
+ {
+ this.pathString = pathString;
+ path = generatePath(pathString);
+ isValid = this.path != null;
+ }
+
+ /**
+ * Provides status string for a TreePath instance.
+ * @param path TreePath instance.
+ * @return pathString.
+ */
+ public String getStringForPath(TreePath path)
+ {
+ setPath(path);
+ return pathString;
+ }
+
+ /**
+ *Provides TreePath for a given status string. In case of invalid string returns null.
+ * @param statusString
+ * @return path.
+ */
+ public TreePath getPathForString(String statusString)
+ {
+ setPathString(statusString);
+ return path;
+ }
+
+ /**
+ * Constructs a status string from the path.
+ * @param path
+ * @return the status string.
+ */
+ private String generatePathString(TreePath path)
+ {
+ StringBuilder pathStringBuilder = new StringBuilder();
+ while (path.getParentPath() != null)
+ {
+ Object object = path.getLastPathComponent();
+ pathStringBuilder.insert(0, "/" + getObjectName(object));
+ path = path.getParentPath();
+ }
+ pathStringBuilder.delete(0, 1);
+ return pathStringBuilder.toString();
+ }
+
+ /**
+ * Constructs TreePath from Status String.
+ * @param pathString
+ * @return a TreePath, or null if there is an error.
+ */
+ private TreePath generatePath(String pathString)
+ {
+ ArrayList<String> nodes = parsePathString(pathString);
+ if (nodes == null)
+ {
+ return null;
+ }
+ Object obj = rootNode;
+ TreePath treePath = new TreePath(obj);
+ for (String node : nodes)
+ {
+ obj = searchNode(obj, node);
+ treePath = treePath.pathByAddingChild(obj);
+ }
+ return treePath;
+ }
+
+ /**
+ * Get the object name of a tree node. If the given node of the tree is a MapEntry, its key is
+ * used as node identifier; if it is an ArrayEntry, then its index is used as identifier.
+ *
+ * @param treeNode node of a tree.
+ * @return the name of the node.
+ * @throws IllegalArgumentException if there is an unknown treeNode type.
+ */
+ private String getObjectName(Object treeNode)
+ {
+ if (treeNode instanceof MapEntry)
+ {
+ MapEntry entry = (MapEntry) treeNode;
+ COSName key = (COSName) entry.getKey();
+ return key.getName();
+ }
+ if (treeNode instanceof ArrayEntry)
+ {
+ ArrayEntry entry = (ArrayEntry) treeNode;
+ return "[" + entry.getIndex() + "]";
+ }
+ throw new IllegalArgumentException("Unknown treeNode type: " + treeNode.getClass().getName());
+ }
+
+ /**
+ * Parses a string and lists all the nodes.
+ *
+ * @param path a tree path.
+ * @return a list of nodes, or null if there is an empty node.
+ */
+ private ArrayList<String> parsePathString(String path)
+ {
+ ArrayList<String> nodes = new ArrayList<String>();
+ for (String node : path.split("/"))
+ {
+ node = node.trim();
+ if (node.startsWith("["))
+ {
+ node = node.replace("]", "").replace("[", "");
+ }
+ node = node.trim();
+ if (node.isEmpty())
+ {
+ return null;
+ }
+ nodes.add(node);
+ }
+ return nodes;
+ }
+
+ /**
+ * An object is searched in the tree structure using the identifiers parsed earlier step.
+ * @param obj
+ * @param searchStr
+ * @return
+ */
+ private Object searchNode(Object obj, String searchStr)
+ {
+ if (obj instanceof MapEntry)
+ {
+ obj = ((MapEntry) obj).getValue();
+ }
+ else if (obj instanceof ArrayEntry)
+ {
+ obj = ((ArrayEntry) obj).getValue();
+ }
+ if (obj instanceof COSObject)
+ {
+ obj = ((COSObject) obj).getObject();
+ }
+ if (obj instanceof COSDictionary)
+ {
+ COSDictionary dic = (COSDictionary) obj;
+ if (dic.containsKey(searchStr))
+ {
+ MapEntry entry = new MapEntry();
+ entry.setKey(COSName.getPDFName(searchStr));
+ entry.setValue(dic.getItem(searchStr));
+ return entry;
+ }
+ }
+ else if (obj instanceof COSArray)
+ {
+ int index = Integer.parseInt(searchStr);
+ COSArray array = (COSArray) obj;
+ if (index <= array.size() - 1)
+ {
+ ArrayEntry entry = new ArrayEntry();
+ entry.setIndex(index);
+ entry.setValue(array.getObject(index));
+ return entry;
+ }
+ }
+ return null;
+ }
+}
Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatus.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java?rev=1681588&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java Mon May 25 13:30:54 2015
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pdfbox.tools.pdfdebugger.treestatus;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.border.BevelBorder;
+import javax.swing.border.Border;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+/**
+ * @author Khyrul Bashar
+ */
+public class TreeStatusPane implements TreeSelectionListener
+{
+ private TreeStatus statusObj;
+ private JTree tree;
+
+ private JTextField statusField;
+ private JPanel panel;
+ private Border defaultBorder;
+ private Border errorBorder;
+ private final Action textInputAction = new AbstractAction()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ TreePath path = statusObj.getPathForString(statusField.getText());
+ if (statusObj.isValid)
+ {
+ tree.setSelectionPath(path);
+ }
+ else
+ {
+ statusField.setBorder(errorBorder);
+ }
+ }
+ };
+
+ /**
+ * Constructor.
+ * @param targetTree The tree instance that this status pane will correspond.
+ */
+ public TreeStatusPane(JTree targetTree)
+ {
+ tree = targetTree;
+ init();
+ }
+
+ private void init()
+ {
+ panel = new JPanel(new BorderLayout());
+ statusField = new JTextField();
+ statusField.setEditable(false);
+ panel.add(statusField);
+ defaultBorder = new BevelBorder(BevelBorder.LOWERED);
+ errorBorder = new BevelBorder(BevelBorder.LOWERED, Color.RED, Color.RED);
+ statusField.setAction(textInputAction);
+ tree.addTreeSelectionListener(this);
+ }
+
+ /**
+ * Return the panel of this TreeStatusPane.
+ * @return JPanel instance.
+ */
+ public JPanel getPanel()
+ {
+ return panel;
+ }
+
+ /**
+ * In case of document changing this should be called to update TreeStatus value of the pane.
+ * @param statusObj TreeStatus instance.
+ */
+ public void updateTreeStatus(TreeStatus statusObj)
+ {
+ statusField.setEditable(true);
+ this.statusObj = statusObj;
+ updateText(null);
+ }
+
+ private void updateText(String statusString)
+ {
+ statusField.setText(statusString);
+ if (!statusField.getBorder().equals(defaultBorder))
+ {
+ statusField.setBorder(defaultBorder);
+ }
+ }
+
+ /**
+ * Tree selection change listener which updates status string.
+ * @param treeSelectionEvent
+ */
+
+ @Override
+ public void valueChanged(TreeSelectionEvent treeSelectionEvent)
+ {
+ TreePath path = treeSelectionEvent.getPath();
+ updateText(statusObj.getStringForPath(path));
+ }
+}
Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java
------------------------------------------------------------------------------
svn:eol-style = native