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