1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 package org.apache.openoffice.ooxml.viewer; 23 24 import java.awt.event.MouseEvent; 25 import java.awt.event.MouseMotionListener; 26 27 import javax.swing.JTree; 28 import javax.swing.SwingUtilities; 29 import javax.swing.event.TreeSelectionEvent; 30 import javax.swing.event.TreeSelectionListener; 31 import javax.swing.tree.DefaultMutableTreeNode; 32 import javax.swing.tree.DefaultTreeModel; 33 import javax.swing.tree.TreeModel; 34 import javax.swing.tree.TreeNode; 35 import javax.swing.tree.TreePath; 36 37 import org.apache.openoffice.ooxml.framework.part.ContentType; 38 import org.apache.openoffice.ooxml.framework.part.OOXMLPackage; 39 import org.apache.openoffice.ooxml.framework.part.Part; 40 import org.apache.openoffice.ooxml.framework.part.PartName; 41 42 /** Overview of the individual parts/streams in an OOXML file. 43 */ 44 @SuppressWarnings("serial") 45 public class StreamView 46 extends JTree 47 implements TreeSelectionListener, MouseMotionListener 48 { 49 /** Create a new PartsView object for the given OOXML file. 50 * When the user clicks on one part entry then the DetailViewManager is 51 * called and asked to display the part. 52 */ StreamView( final DetailViewManager aDetailViewManager, final OOXMLPackage aPackage)53 StreamView ( 54 final DetailViewManager aDetailViewManager, 55 final OOXMLPackage aPackage) 56 { 57 maDetailViewManager = aDetailViewManager; 58 maOOXMLPackage = aPackage; 59 getSelectionModel().addTreeSelectionListener(this); 60 61 // Listen for motion events so that the tooltip can be set according to 62 // the entry under the mouse pointer. 63 addMouseMotionListener(this); 64 65 // Create a tree model for the streams in the (zip) file, set the model 66 // asynchronously at the JTree and finally expand all nodes. 67 final TreeModel aModel = CreateTreeModel(aPackage); 68 SwingUtilities.invokeLater(new Runnable() 69 { 70 public void run() 71 { 72 setModel(aModel); 73 for (int nIndex=0; nIndex<getRowCount(); ++nIndex) 74 { 75 expandRow(nIndex); 76 } 77 } 78 }); 79 80 setToolTipText("hallo"); 81 } 82 83 84 85 CreateTreeModel(final OOXMLPackage aPackage)86 private TreeModel CreateTreeModel (final OOXMLPackage aPackage) 87 { 88 final DefaultMutableTreeNode aRootNode = new DefaultMutableTreeNode( 89 aPackage.getFileName()); 90 final DefaultTreeModel aModel = new DefaultTreeModel(aRootNode); 91 try 92 { 93 for (final String sStreamName : aPackage.listStreamNames()) 94 { 95 DefaultMutableTreeNode aNode = aRootNode; 96 for (final String sPart : sStreamName.split("/")) 97 { 98 DefaultMutableTreeNode aChild = GetChildNodeForName(aNode, sPart); 99 if (aChild == null) 100 { 101 aChild = new DefaultMutableTreeNode(sPart); 102 aNode.add(aChild); 103 } 104 105 aNode = aChild; 106 } 107 } 108 } 109 catch (Exception e) 110 { 111 e.printStackTrace(); 112 } 113 return aModel; 114 } 115 116 117 118 ShowInitialPart()119 public void ShowInitialPart () 120 { 121 final Part aPart = maOOXMLPackage.getOfficeDocumentPart(); 122 MakePartVisible(aPart); 123 maDetailViewManager.ShowPart(aPart); 124 } 125 126 127 128 GetChildNodeForName(final TreeNode aNode, final String sName)129 private DefaultMutableTreeNode GetChildNodeForName (final TreeNode aNode, final String sName) 130 { 131 for (int nIndex=0; nIndex<aNode.getChildCount(); ++nIndex) 132 { 133 final TreeNode aChild = aNode.getChildAt(nIndex); 134 if (aChild.toString().equals(sName)) 135 { 136 return (DefaultMutableTreeNode)aChild; 137 } 138 } 139 return null; 140 } 141 142 143 144 145 /** Callback for clicks on the part view. 146 */ 147 @Override valueChanged(final TreeSelectionEvent aEvent)148 public void valueChanged (final TreeSelectionEvent aEvent) 149 { 150 final TreePath aPath = aEvent.getNewLeadSelectionPath(); 151 if (aPath != null) 152 { 153 final String sPath = GetPackagePathForTreePath(aPath); 154 final PartName aName = new PartName(sPath); 155 final ContentType eType = maOOXMLPackage.getPart( 156 aName).getContentType(); 157 maDetailViewManager.ShowPart( 158 aName, 159 eType); 160 } 161 } 162 163 164 165 166 @Override mouseDragged(final MouseEvent aEvent)167 public void mouseDragged (final MouseEvent aEvent) 168 { 169 } 170 171 172 173 174 @Override mouseMoved(final MouseEvent aEvent)175 public void mouseMoved (final MouseEvent aEvent) 176 { 177 final int nRow = getRowForLocation(aEvent.getX(), aEvent.getY()); 178 if (nRow >= 0) 179 { 180 final String sPath = GetPackagePathForTreePath(getPathForRow(nRow)); 181 SetPartUnderMouse(sPath); 182 } 183 } 184 185 186 187 GetPackagePathForTreePath(final TreePath aPath)188 private String GetPackagePathForTreePath (final TreePath aPath) 189 { 190 final StringBuffer sPath = new StringBuffer(""); 191 final Object aNodes[] = aPath.getPath(); 192 for (int nIndex=1; nIndex<aNodes.length; ++nIndex) 193 { 194 sPath.append("/"); 195 sPath.append(aNodes[nIndex].toString()); 196 } 197 return sPath.toString(); 198 } 199 200 201 202 SetPartUnderMouse(final String sPartPath)203 private void SetPartUnderMouse (final String sPartPath) 204 { 205 if (msPartPathUnderMouse==null 206 || ! msPartPathUnderMouse.equals(sPartPath)) 207 { 208 msPartPathUnderMouse = sPartPath; 209 210 final ContentType eType = maOOXMLPackage.getPart( 211 new PartName(msPartPathUnderMouse)).getContentType(); 212 String sToolTipText = eType.toString(); 213 if ( ! eType.GetLongName().isEmpty()) 214 sToolTipText += " (" + eType.GetLongName() + ")"; 215 setToolTipText(sToolTipText); 216 } 217 } 218 219 220 221 MakePartVisible(final Part aPart)222 private void MakePartVisible (final Part aPart) 223 { 224 final String[] aPathParts = aPart.getPartName().GetFullname().substring(1).split("/"); 225 final TreeNode[] aTreeNodePath = new TreeNode[aPathParts.length+1]; 226 TreeNode aNode = (TreeNode)getModel().getRoot(); 227 int nDepth = 0; 228 aTreeNodePath[nDepth++] = aNode; 229 for (final String sPathPart : aPathParts) 230 { 231 boolean bFoundChild = false; 232 for (int nIndex=0; nIndex<aNode.getChildCount(); ++nIndex) 233 { 234 final TreeNode aChildNode = aNode.getChildAt(nIndex); 235 final String sChildName = aChildNode.toString(); 236 if (sChildName.equals(sPathPart)) 237 { 238 aNode = aChildNode; 239 aTreeNodePath[nDepth++] = aNode; 240 bFoundChild = true; 241 break; 242 } 243 } 244 if ( ! bFoundChild) 245 return; 246 } 247 248 SelectNode(new TreePath(aTreeNodePath)); 249 } 250 251 252 253 SelectNode(final TreePath aTreePath)254 private void SelectNode (final TreePath aTreePath) 255 { 256 // getSelectionModel().setSelectionPath(aTreePath); 257 // scrollPathToVisible(aTreePath); 258 } 259 260 261 262 263 private final DetailViewManager maDetailViewManager; 264 private final OOXMLPackage maOOXMLPackage; 265 private String msPartPathUnderMouse; 266 } 267