1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  *  The Contents of this file are made available subject to the terms of
5  *  the BSD license.
6  *
7  *  Copyright 2000, 2010 Oracle and/or its affiliates.
8  *  All rights reserved.
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *  1. Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *  2. Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in the
17  *     documentation and/or other materials provided with the distribution.
18  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
19  *     contributors may be used to endorse or promote products derived
20  *     from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *************************************************************************/
35 
36 import com.sun.star.beans.Property;
37 import com.sun.star.beans.PropertyValue;
38 import com.sun.star.lang.NullPointerException;
39 import com.sun.star.reflection.XConstantTypeDescription;
40 import com.sun.star.reflection.XIdlMethod;
41 import com.sun.star.uno.Type;
42 import java.awt.BorderLayout;
43 import java.awt.Container;
44 import java.awt.Dimension;
45 import java.awt.event.KeyAdapter;
46 import java.awt.event.KeyEvent;
47 import java.awt.event.MouseAdapter;
48 import java.awt.event.MouseEvent;
49 import javax.swing.JPanel;
50 import javax.swing.JScrollBar;
51 import javax.swing.JScrollPane;
52 import javax.swing.JSplitPane;
53 import javax.swing.JTextArea;
54 import javax.swing.JTextField;
55 import javax.swing.JTree;
56 import javax.swing.event.TreeSelectionEvent;
57 import javax.swing.event.TreeSelectionListener;
58 import javax.swing.event.TreeWillExpandListener;
59 import javax.swing.tree.DefaultTreeSelectionModel;
60 import javax.swing.tree.ExpandVetoException;
61 import javax.swing.tree.TreePath;
62 import javax.swing.tree.TreeSelectionModel;
63 
64 
65 
66 public class SwingTreeControlProvider implements XTreeControlProvider{
67     private JTextArea jtxtGeneratedSourceCode = new JTextArea();
68     private JTextField jtxtFilter = new JTextField();
69     private javax.swing.JLabel jlblFilter = new javax.swing.JLabel("Set a filter");
70     private JTree jTree = new javax.swing.JTree();
71     private XDialogProvider m_xDialogProvider;
72     private HideableTreeModel treeModel;
73     private InspectorPane m_oInspectorPane;
74     private Object oUserDefinedObject = null;
75     private boolean bIsUserDefined = false;
76     private SwingUnoNode oRootNode;
77 
78     private final int nDIALOGWIDTH = 800;
79 
80 
81 
SwingTreeControlProvider(XDialogProvider _xDialogProvider)82     public SwingTreeControlProvider(XDialogProvider _xDialogProvider){
83         m_xDialogProvider = _xDialogProvider;
84     }
85 
86 
addInspectorPane(InspectorPane _oInspectorPane)87     public void addInspectorPane(InspectorPane _oInspectorPane){
88         m_oInspectorPane = _oInspectorPane;
89     }
90 
getInspectorPane()91     public InspectorPane getInspectorPane() throws NullPointerException{
92         if (m_oInspectorPane == null){
93             throw new NullPointerException("InspectorPage has not been added to TreeControl");
94         }
95         else{
96             return m_oInspectorPane;
97         }
98     }
99 
ComponentSelector(Object _oRootObject, String _sRootTreeNodeName)100     private void ComponentSelector(Object _oRootObject, String _sRootTreeNodeName) {
101         oRootNode = new SwingUnoNode(_oRootObject);
102         oRootNode.setLabel(_sRootTreeNodeName);
103         treeModel = new HideableTreeModel(oRootNode);
104         jTree.setModel(treeModel);
105         jTree.setRootVisible(true);
106         jTree.setVisible(true);
107         oRootNode.setFoldable(true);
108         enableFilterElements(null);
109     }
110 
111 
112 
insertTopPanel(JPanel _jPnlCenter)113     private void insertTopPanel(JPanel _jPnlCenter){
114         javax.swing.JPanel jPnlTop = new javax.swing.JPanel(new BorderLayout(10, 10));
115         jPnlTop.setPreferredSize(new java.awt.Dimension(nDIALOGWIDTH, 20));
116         jlblFilter.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
117         jlblFilter.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
118         jPnlTop.add(jlblFilter, java.awt.BorderLayout.WEST);
119         jtxtFilter.setHorizontalAlignment(javax.swing.JTextField.LEFT);
120         jtxtFilter.setPreferredSize(new java.awt.Dimension(200, 10));
121         jtxtFilter.addKeyListener(new InspectorKeyFilterAdapter());
122         jPnlTop.add(jtxtFilter, java.awt.BorderLayout.CENTER);
123         _jPnlCenter.add(jPnlTop, java.awt.BorderLayout.NORTH);
124     }
125 
126 
insertBottomPanel(JSplitPane _jSplitPane)127     private void insertBottomPanel(JSplitPane _jSplitPane){ //JPanel _jPnlCenter){
128         jtxtGeneratedSourceCode.setTabSize(4);
129         jtxtGeneratedSourceCode.getAccessibleContext().setAccessibleName("generated SourceCode");
130         JScrollPane jScrollPane = new JScrollPane(jtxtGeneratedSourceCode);
131         jScrollPane.setPreferredSize(new Dimension(nDIALOGWIDTH,205));
132         jtxtGeneratedSourceCode.setEditable(false);
133         _jSplitPane.setBottomComponent(jScrollPane);
134     }
135 
insertBorderPanes(Container _cp)136         private void insertBorderPanes(Container _cp){
137             JPanel jPnlEast  = new JPanel(new BorderLayout());
138             JPanel jPnlNorth = new JPanel(new BorderLayout());
139             JPanel jPnlSouth = new JPanel(new BorderLayout());
140             JPanel jPnlWest = new JPanel(new BorderLayout());
141             _cp.add(jPnlNorth, java.awt.BorderLayout.NORTH);
142             jPnlWest.setPreferredSize(new java.awt.Dimension(10, 10));
143             _cp.add(jPnlWest, java.awt.BorderLayout.WEST);
144             jPnlEast.setPreferredSize(new java.awt.Dimension(10, 10));
145             _cp.add(jPnlEast, java.awt.BorderLayout.EAST);
146             jPnlSouth.setPreferredSize(new java.awt.Dimension(10, 10));
147             _cp.add(jPnlSouth, java.awt.BorderLayout.SOUTH);
148         }
149 
150 
enableFilterElements(XUnoNode _oUnoNode)151         public String enableFilterElements(XUnoNode _oUnoNode){
152             String sFilter ="";
153             boolean bIsFacetteNode = isFacetteNode(_oUnoNode);
154             this.jtxtFilter.setEnabled(bIsFacetteNode);
155             this.jlblFilter.setEnabled(bIsFacetteNode);
156             sFilter = m_oInspectorPane.getFilter(_oUnoNode);
157             jtxtFilter.setText(sFilter);
158             return sFilter;
159         }
160 
161 
162         private class InspectorKeyFilterAdapter extends KeyAdapter{
163             @Override
keyReleased(KeyEvent e)164             public void keyReleased(KeyEvent e){
165                 String sFilter = jtxtFilter.getText();
166                 SwingTreePathProvider oSwingTreePathProvider = new SwingTreePathProvider(jTree.getSelectionPath());
167                 XUnoNode oUnoNode = oSwingTreePathProvider.getLastPathComponent();
168                 if (oUnoNode instanceof XUnoFacetteNode){
169                     m_oInspectorPane.applyFilter((XUnoFacetteNode) oUnoNode, sFilter);
170                 }
171             }
172         }
173 
174 
175 
176         /** Inspect the given object for methods, properties, interfaces, and
177          * services.
178          * @param _oUserDefinedObject The object to inspect
179          * @throws RuntimeException If
180          */
inspect(java.lang.Object _oUserDefinedObject, String _sTitle)181         public Object inspect(java.lang.Object _oUserDefinedObject, String _sTitle) throws com.sun.star.uno.RuntimeException {
182         JPanel jPnlContainer = new javax.swing.JPanel(new BorderLayout(10, 10));
183         try {
184             javax.swing.JPanel jPnlCenter = new javax.swing.JPanel();
185             bIsUserDefined = (_oUserDefinedObject != null);
186             if (bIsUserDefined){
187                 oUserDefinedObject = _oUserDefinedObject;
188                 m_oInspectorPane.setTitle(_sTitle);
189             }
190             javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
191             TreeSelectionModel tsm = new DefaultTreeSelectionModel();
192             tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
193             jTree.setSelectionModel(tsm);
194             jTree.setVisible(false);
195             jPnlCenter.setLayout(new java.awt.BorderLayout(10, 10));
196             jPnlCenter.getAccessibleContext().setAccessibleName("inspection tab view");
197             insertTopPanel(jPnlCenter);
198             jScrollPane1.setViewportView(jTree);
199             jScrollPane1.setPreferredSize(new java.awt.Dimension(600, 600));
200             jScrollPane1.getAccessibleContext().setAccessibleName("API view scroll pane");
201 
202             JScrollBar jHScrollBar = jScrollPane1.createHorizontalScrollBar();
203             jHScrollBar.getAccessibleContext().setAccessibleName("API view horizontal scroll bar");
204             jScrollPane1.setHorizontalScrollBar(jHScrollBar);
205 
206             JScrollBar jVScrollBar = jScrollPane1.createVerticalScrollBar();
207             jVScrollBar.getAccessibleContext().setAccessibleName("API view vertical scroll bar");
208             jScrollPane1.setVerticalScrollBar(jVScrollBar);
209 
210             JSplitPane jSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
211             jSplitPane.setTopComponent(jScrollPane1);
212             jPnlCenter.add(jSplitPane, java.awt.BorderLayout.CENTER);
213             jSplitPane.setDividerLocation(500);
214             insertBottomPanel(jSplitPane);
215             UnoTreeRenderer oUnoTreeRenderer = new UnoTreeRenderer();
216             jTree.setCellRenderer(oUnoTreeRenderer);
217             jTree.addTreeSelectionListener(
218                 new TreeSelectionListener() {
219                     public void valueChanged(TreeSelectionEvent event) {
220                         TreePath tp = event.getNewLeadSelectionPath();
221                         if (tp != null){
222                             XUnoNode oUnoNode = getSelectedNode();
223                             String sFilter = enableFilterElements(oUnoNode);
224                         }
225                     }
226                 }
227                 );
228             //  Add KeyListener for help
229             jTree.addKeyListener( new java.awt.event.KeyAdapter() {
230                 @Override
231                 public void keyReleased(java.awt.event.KeyEvent event) {
232                     if ( event.getKeyCode() == KeyEvent.VK_F1 ) {
233                         //  function key F1 pressed
234                         TreePath aTreePath = jTree.getSelectionPath();
235                         SwingUnoNode oUnoNode = (SwingUnoNode) aTreePath.getLastPathComponent();
236                         oUnoNode.openIdlDescription(m_xDialogProvider.getIDLPath());
237                     }
238                 }
239             });
240             jTree.addMouseListener(new MouseAdapter() {
241                 @Override
242                 public void mousePressed (MouseEvent e) {
243                     if (e.isPopupTrigger()){
244                         m_oInspectorPane.showPopUpMenu(e.getComponent(), e.getX(), e.getY());
245                     }
246                     //unfortunately under Windows the method "isPopupTrigger" always returns false
247                     else if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) == MouseEvent.BUTTON3_DOWN_MASK){
248                         m_oInspectorPane.showPopUpMenu(e.getComponent(), e.getX(), e.getY());
249                     }
250                 }
251             });
252             jPnlContainer.add(jPnlCenter, java.awt.BorderLayout.CENTER);
253             insertBorderPanes(jPnlContainer);
254             if (this.bIsUserDefined){
255                 ComponentSelector(oUserDefinedObject, m_oInspectorPane.getTitle());
256             }
257             m_xDialogProvider.addInspectorPage(m_oInspectorPane.getTitle(), jPnlContainer);
258             addTreeExpandListener();
259             }
260             catch( Exception exception ) {
261                 exception.printStackTrace(System.err);
262             }
263             return jPnlContainer;
264         }
265 
getModel()266         public HideableTreeModel getModel(){
267             return  treeModel;
268         }
269 
270 
addTreeExpandListener()271         public void addTreeExpandListener(){
272             jTree.addTreeWillExpandListener(
273                 new TreeWillExpandListener() {
274                     public void treeWillExpand(javax.swing.event.TreeExpansionEvent event) throws javax.swing.tree.ExpandVetoException {
275                         SwingTreePathProvider oSwingTreePathProvider = new SwingTreePathProvider(event.getPath());
276                         XUnoNode oUnoNode = oSwingTreePathProvider.getLastPathComponent();
277                         if (!m_oInspectorPane.expandNode(oUnoNode)){
278                             throw new ExpandVetoException(event);
279                         }
280                     }
281 
282                     public void treeWillCollapse( javax.swing.event.TreeExpansionEvent evt) throws javax.swing.tree.ExpandVetoException {
283                     }
284             });
285         }
286 
287 
setSourceCode(String _sSourceCode)288     public void setSourceCode(String _sSourceCode){
289         jtxtGeneratedSourceCode.setText(_sSourceCode);
290     }
291 
292 
getSelectedPath()293     public XTreePathProvider getSelectedPath(){
294         return new SwingTreePathProvider(jTree.getSelectionPath());
295     }
296 
297 
expandPath(XTreePathProvider _xTreePathProvider)298     public void expandPath(XTreePathProvider _xTreePathProvider) throws ClassCastException{
299         SwingTreePathProvider oSwingTreePathProvider = (SwingTreePathProvider) _xTreePathProvider;
300         jTree.expandPath(oSwingTreePathProvider.getSwingTreePath());
301     }
302 
303 
getSelectedNode()304     public XUnoNode getSelectedNode(){
305         XUnoNode oUnoNode = null;
306         TreePath aTreePath = jTree.getSelectionPath();
307         Object oNode = aTreePath.getLastPathComponent();
308         if (oNode instanceof XUnoNode){
309             oUnoNode = (XUnoNode) oNode;
310         }
311         return oUnoNode;
312     }
313 
314 
nodeInserted(XUnoNode _oParentNode, XUnoNode _oChildNode, int index)315     public void nodeInserted(XUnoNode _oParentNode, XUnoNode _oChildNode, int index) {
316         getModel().nodeInserted(_oParentNode, _oChildNode, _oParentNode.getChildCount()-1);
317     }
318 
319 
nodeChanged(XUnoNode _oNode)320     public void nodeChanged(XUnoNode _oNode) {
321         getModel().nodeChanged(_oNode);
322     }
323 
324 
setNodeVisible(Object node, boolean v)325     public boolean setNodeVisible(Object node, boolean v) {
326        return getModel().setNodeVisible(node, v);
327     }
328 
329 
isPropertyNode(XUnoNode _oUnoNode)330     public boolean isPropertyNode(XUnoNode _oUnoNode){
331         return (_oUnoNode instanceof SwingUnoPropertyNode);
332     }
333 
334 
isMethodNode(XUnoNode _oUnoNode)335     public boolean isMethodNode(XUnoNode _oUnoNode){
336         return (_oUnoNode instanceof SwingUnoMethodNode);
337     }
338 
339 
isFacetteNode(XUnoNode _oUnoNode)340     public boolean isFacetteNode(XUnoNode _oUnoNode){
341         return (_oUnoNode instanceof SwingUnoFacetteNode);
342     }
343 
344 
addUnoNode(Object _oUnoObject)345     public XUnoNode addUnoNode(Object _oUnoObject){
346         return new SwingUnoNode(_oUnoObject);
347     }
348 
349 
addUnoNode(Object _oUnoObject, Type _aType)350     public XUnoNode addUnoNode(Object _oUnoObject, Type _aType){
351         return new SwingUnoNode(_oUnoObject, _aType);
352     }
353 
354 
addUnoFacetteNode(XUnoNode _oParentNode, String _sNodeDescription, Object _oUnoObject)355     public XUnoFacetteNode addUnoFacetteNode(XUnoNode _oParentNode, String _sNodeDescription, Object _oUnoObject){
356         SwingUnoFacetteNode oSwingUnoFacetteNode = new SwingUnoFacetteNode(_oUnoObject);
357         oSwingUnoFacetteNode.setLabel(_sNodeDescription);
358         if (_oParentNode != null){
359             ((SwingUnoNode) _oParentNode).addChildNode(oSwingUnoFacetteNode);
360         }
361         return oSwingUnoFacetteNode;
362     }
363 
364 
addMethodNode(Object _objectElement, XIdlMethod _xIdlMethod)365     public XUnoMethodNode addMethodNode(Object _objectElement, XIdlMethod _xIdlMethod){
366         SwingUnoMethodNode oSwingUnoMethodNode = new SwingUnoMethodNode(_xIdlMethod, _objectElement, m_xDialogProvider);
367         return oSwingUnoMethodNode;
368     }
369 
370 
addUnoPropertyNodeWithName(Property _aProperty)371     public XUnoPropertyNode addUnoPropertyNodeWithName(Property _aProperty){
372         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
373         oUnoPropertyNode.setLabel("Name: " + _aProperty.Name);
374         return oUnoPropertyNode;
375     }
376 
377 
addUnoPropertyNodeWithHandle(Property _aProperty)378     public XUnoPropertyNode addUnoPropertyNodeWithHandle(Property _aProperty){
379         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
380         oUnoPropertyNode.setLabel("Handle: " + _aProperty.Handle);
381         return oUnoPropertyNode;
382     }
383 
384 
addUnoPropertyNodeWithType(Property _aProperty)385     public XUnoPropertyNode addUnoPropertyNodeWithType(Property _aProperty){
386         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
387         oUnoPropertyNode.setLabel("Type: " + _aProperty.Type.getTypeName());
388         return oUnoPropertyNode;
389     }
390 
391 
addUnoPropertyNodeWithAttributesDescription(Property _aProperty)392     public XUnoPropertyNode addUnoPropertyNodeWithAttributesDescription(Property _aProperty){
393         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
394         XConstantTypeDescription[] xPropertyAttributesTypeDescriptions = Introspector.getIntrospector().getFieldsOfConstantGroup("com.sun.star.beans.PropertyAttribute");
395         String sDisplay = Introspector.getIntrospector().getConstantDisplayString(_aProperty.Attributes, xPropertyAttributesTypeDescriptions, "Attributes: ");
396         oUnoPropertyNode.setLabel(sDisplay);
397         return oUnoPropertyNode;
398     }
399 
400 
addUnoPropertyNode(Object _oUnoObject, Property _aProperty)401     public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, Property _aProperty){
402         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty, _oUnoObject, null);
403         oUnoPropertyNode.setPropertyNodeType(XUnoPropertyNode.nPROPERTYSETINFOTYPE);
404         oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyDescription(_aProperty, null));
405         return oUnoPropertyNode;
406     }
407 
408 
addUnoPropertyNode(Object _oUnoObject, Property _aProperty, Object _oUnoReturnObject)409     public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, Property _aProperty, Object _oUnoReturnObject){
410         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty, _oUnoObject, _oUnoReturnObject);
411         oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyDescription(_aProperty, _oUnoReturnObject));
412         return oUnoPropertyNode;
413     }
414 
415 
addUnoPropertyNode(Object _oUnoObject, PropertyValue _aPropertyValue, Object _oReturnObject)416     public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, PropertyValue _aPropertyValue, Object _oReturnObject){
417         SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aPropertyValue, _oUnoObject, _oReturnObject);
418         oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyValueDescription(_aPropertyValue));
419         return oUnoPropertyNode;
420     }
421 }
422 
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
424