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 import javax.swing.*;
23 import javax.swing.tree.*;
24 import javax.swing.table.*;
25 import javax.swing.event.*;
26 import javax.swing.border.*;
27 import java.awt.*;
28 import java.awt.event.*;
29 import java.util.*;
30 import java.beans.*;
31 
32 import com.sun.star.uno.UnoRuntime;
33 import com.sun.star.uno.Exception;
34 import com.sun.star.uno.Any;
35 import com.sun.star.uno.AnyConverter;
36 import com.sun.star.uno.Type;
37 import com.sun.star.uno.XComponentContext;
38 
39 import com.sun.star.lang.XMultiComponentFactory;
40 import com.sun.star.lang.XComponent;
41 import com.sun.star.frame.XModel;
42 import com.sun.star.frame.FrameSearchFlag;
43 import com.sun.star.frame.XDispatchProvider;
44 import com.sun.star.frame.XDispatchHelper;
45 import com.sun.star.frame.XDispatch;
46 import com.sun.star.util.XURLTransformer;
47 import com.sun.star.beans.*;
48 import com.sun.star.script.XInvocation;
49 
50 import com.sun.star.lib.uno.helper.PropertySet;
51 
52 import com.sun.star.script.browse.XBrowseNode;
53 import com.sun.star.script.browse.BrowseNodeTypes;
54 import com.sun.star.script.browse.XBrowseNodeFactory;
55 import com.sun.star.script.browse.BrowseNodeFactoryViewTypes;
56 import com.sun.star.script.provider.XScriptContext;
57 import com.sun.star.script.provider.XScript;
58 import com.sun.star.script.provider.XScriptProvider;
59 
60 public class ScriptSelector {
61 
62     private static final int BIG_GAP = 10;
63     private static final int MED_GAP = 5;
64 
65     private ScriptSelectorPanel selectorPanel;
66 
ScriptSelector()67     public ScriptSelector()
68     {
69     }
70 
showOrganizer(final XScriptContext ctxt)71     public void showOrganizer(final XScriptContext ctxt)
72     {
73         try {
74             XBrowseNode root = getRootNode(ctxt);
75 
76             final XScriptProvider msp =
77                 (XScriptProvider)UnoRuntime.queryInterface(
78                  XScriptProvider.class, root);
79 
80             final JFrame client = new JFrame("Script");
81 
82             selectorPanel = new ScriptSelectorPanel(root);
83 
84             final JButton runButton, closeButton, createButton,
85                           editButton, deleteButton;
86 
87             runButton = new JButton("Run");
88             runButton.setEnabled(false);
89 
90             closeButton = new JButton("Close");
91 
92             editButton = new JButton("Edit");
93             editButton.setEnabled(false);
94 
95             JPanel northButtons =
96                 new JPanel(new GridLayout(2, 1, MED_GAP, MED_GAP));
97 
98             northButtons.add(runButton);
99             northButtons.add(closeButton);
100 
101             createButton = new JButton("Create");
102             createButton.setEnabled(false);
103 
104             deleteButton = new JButton("Delete");
105             deleteButton.setEnabled(false);
106 
107             JPanel southButtons =
108                 new JPanel(new GridLayout(3, 1, MED_GAP, MED_GAP));
109 
110             southButtons.add(editButton);
111             southButtons.add(createButton);
112             southButtons.add(deleteButton);
113 
114             selectorPanel.tree.addTreeSelectionListener(
115                 new TreeSelectionListener() {
116                     public void valueChanged(TreeSelectionEvent e) {
117                         XBrowseNode xbn = selectorPanel.getSelection();
118                         XPropertySet props = (XPropertySet)
119                             UnoRuntime.queryInterface(XPropertySet.class, xbn);
120 
121                         checkEnabled(props, "Creatable", createButton);
122                         checkEnabled(props, "Deletable", deleteButton);
123                         checkEnabled(props, "Editable", editButton);
124 
125                         if (xbn != null &&
126                             xbn.getType() == BrowseNodeTypes.SCRIPT)
127                         {
128                             runButton.setEnabled(true);
129                         }
130                         else
131                         {
132                             runButton.setEnabled(false);
133                         }
134                     }
135                 }
136             );
137 
138             ActionListener listener = new ActionListener() {
139                 public void actionPerformed(ActionEvent event) {
140                     if (event.getSource() == runButton) {
141                         String uri = selectorPanel.textField.getText();
142 
143                         try {
144                             XScript script = msp.getScript(uri);
145 
146                             Object[][] out = new Object[1][0];
147                             out[0] = new Object[0];
148 
149                             short[][] num = new short[1][0];
150                             num[0] = new short[0];
151 
152                             script.invoke(new Object[0], num, out);
153                         }
154                         catch (Exception e) {
155                             e.printStackTrace();
156                         }
157                     }
158                     else if (event.getSource() == closeButton) {
159                         client.dispose();
160                     }
161                     else if (event.getSource() == editButton) {
162                         DefaultMutableTreeNode node =
163                           (DefaultMutableTreeNode)
164                           selectorPanel.tree.getLastSelectedPathComponent();
165 
166                         if (node == null) return;
167 
168                         showEditor(ctxt, node);
169                     }
170                     else if (event.getSource() == createButton) {
171                         DefaultMutableTreeNode node =
172                           (DefaultMutableTreeNode)
173                           selectorPanel.tree.getLastSelectedPathComponent();
174 
175                         if (node == null) return;
176 
177                         doCreate(ctxt, node);
178                     }
179                     else if (event.getSource() == deleteButton) {
180                         DefaultMutableTreeNode node =
181                           (DefaultMutableTreeNode)
182                           selectorPanel.tree.getLastSelectedPathComponent();
183 
184                         if (node == null) return;
185 
186                         doDelete(ctxt, node);
187                     }
188                 }
189             };
190 
191             runButton.addActionListener(listener);
192             closeButton.addActionListener(listener);
193             createButton.addActionListener(listener);
194             editButton.addActionListener(listener);
195             deleteButton.addActionListener(listener);
196 
197             JPanel buttonPanel = new JPanel(new BorderLayout());
198             buttonPanel.add(northButtons, BorderLayout.NORTH);
199             buttonPanel.add(southButtons, BorderLayout.SOUTH);
200 
201             JPanel mainPanel = new JPanel(new BorderLayout(MED_GAP, MED_GAP));
202             mainPanel.setBorder(
203                 new EmptyBorder(BIG_GAP, BIG_GAP, BIG_GAP, BIG_GAP));
204             mainPanel.add(selectorPanel, BorderLayout.CENTER);
205             mainPanel.add(buttonPanel, BorderLayout.EAST);
206 
207             client.getContentPane().add(mainPanel);
208             client.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
209             client.setSize(500, 350);
210 
211             // set the x and y locations so that the frame is in the
212             // centre of the screen
213             Dimension d = client.getToolkit().getScreenSize();
214 
215             int x = (int)((d.getWidth() - client.getWidth()) / 2);
216             int y = (int)((d.getHeight() - client.getHeight()) / 2);
217 
218             client.setLocation(x, y);
219 
220             client.show();
221         }
222         catch (com.sun.star.uno.RuntimeException rue) {
223             rue.printStackTrace();
224         }
225         catch (java.lang.Exception e) {
226             e.printStackTrace();
227         }
228     }
229 
showOrganizer(final XScriptContext ctxt, final com.sun.star.awt.MouseEvent e)230     public void showOrganizer(final XScriptContext ctxt,
231         final com.sun.star.awt.MouseEvent e)
232     {
233         showOrganizer(ctxt);
234     }
235 
showOrganizer(final XScriptContext ctxt, final com.sun.star.awt.ActionEvent e)236     public void showOrganizer(final XScriptContext ctxt,
237         final com.sun.star.awt.ActionEvent e)
238     {
239         showOrganizer(ctxt);
240     }
241 
doDelete( XScriptContext ctxt, DefaultMutableTreeNode node)242     private void doDelete(
243         XScriptContext ctxt, DefaultMutableTreeNode node)
244     {
245         Object obj = node.getUserObject();
246         XInvocation inv =
247             (XInvocation)UnoRuntime.queryInterface(
248             XInvocation.class, obj);
249         Object[] args = new Object[] { ctxt };
250         try {
251             Object result = inv.invoke("Deletable", args,
252                 new short[1][0], new Object[1][0]);
253 
254             if (result != null && AnyConverter.toBoolean(result) == true)
255             {
256                 selectorPanel.removeNode(node);
257             }
258         }
259         catch (Exception e) {
260             e.printStackTrace();
261         }
262     }
263 
doCreate( XScriptContext ctxt, DefaultMutableTreeNode node)264     private void doCreate(
265         XScriptContext ctxt, DefaultMutableTreeNode node)
266     {
267         Object obj = node.getUserObject();
268         XInvocation inv =
269             (XInvocation)UnoRuntime.queryInterface(
270             XInvocation.class, obj);
271         Object[] args = new Object[] { ctxt };
272         try {
273             Object result = inv.invoke("Creatable", args,
274                 new short[1][0], new Object[1][0]);
275 
276             if (result != null)
277             {
278                 XBrowseNode xbn = (XBrowseNode)
279                     AnyConverter.toObject(new Type(XBrowseNode.class), result);
280                 selectorPanel.addNode(node, xbn);
281             }
282         }
283         catch (Exception e) {
284             e.printStackTrace();
285         }
286     }
287 
showEditor( XScriptContext ctxt, DefaultMutableTreeNode node)288     private void showEditor(
289         XScriptContext ctxt, DefaultMutableTreeNode node)
290     {
291         Object obj = node.getUserObject();
292         XInvocation inv =
293             (XInvocation)UnoRuntime.queryInterface(
294             XInvocation.class, obj);
295         Object[] args = new Object[] { ctxt };
296         try {
297             inv.invoke("Editable", args,
298                 new short[1][0], new Object[1][0]);
299         }
300         catch (Exception e) {
301             e.printStackTrace();
302         }
303     }
304 
checkEnabled(XPropertySet props, String name, JButton button)305     private void checkEnabled(XPropertySet props, String name,
306         JButton button)
307     {
308         boolean enable = false;
309 
310         try
311         {
312             if (props != null)
313             {
314                 Object o = props.getPropertyValue(name);
315                 enable = AnyConverter.toBoolean(
316                     props.getPropertyValue(name));
317             }
318         }
319         catch (com.sun.star.lang.IllegalArgumentException iae)
320         {
321             // leave enable set to false
322         }
323         catch (com.sun.star.beans.UnknownPropertyException upe)
324         {
325             // leave enable set to false
326         }
327         catch (com.sun.star.lang.WrappedTargetException wte)
328         {
329             // leave enable set to false
330         }
331 
332         button.setEnabled(enable);
333     }
334 
getRootNode(XScriptContext ctxt)335     private XBrowseNode getRootNode(XScriptContext ctxt) {
336 
337         XBrowseNode result = null;
338 
339 
340         XComponentContext xcc = ctxt.getComponentContext();
341         XMultiComponentFactory xmcf = xcc.getServiceManager();
342         XBrowseNodeFactory xBrowseFac = (XBrowseNodeFactory)
343             UnoRuntime.queryInterface( XBrowseNodeFactory.class, xcc.getValueByName(
344                 "/singletons/com.sun.star.script.browse.theBrowseNodeFactory") );
345 
346 
347         result = (XBrowseNode)UnoRuntime.queryInterface(
348            XBrowseNode.class, xBrowseFac.createView( BrowseNodeFactoryViewTypes.MACROORGANIZER ) );
349         return result;
350     }
351 }
352 
353 class ScriptSelectorPanel extends JPanel {
354 
355     private XBrowseNode myrootnode = null;
356     public JTextField textField;
357     public JTree tree;
358     public DefaultTreeModel treeModel;
359 
ScriptSelectorPanel(XBrowseNode root)360     public ScriptSelectorPanel(XBrowseNode root)
361     {
362         this.myrootnode = root;
363         initUI();
364     }
365 
getSelection()366     public XBrowseNode getSelection() {
367         DefaultMutableTreeNode node = (DefaultMutableTreeNode)
368             tree.getLastSelectedPathComponent();
369 
370         if (node == null) {
371             return null;
372         }
373 
374         return (XBrowseNode)node.getUserObject();
375     }
376 
initUI()377     private void initUI() {
378         setLayout(new BorderLayout());
379 
380         DefaultMutableTreeNode top =
381             new DefaultMutableTreeNode(myrootnode) {
382                 public String toString() {
383                     return ((XBrowseNode)getUserObject()).getName();
384                 }
385             };
386         initNodes(myrootnode, top);
387         treeModel = new DefaultTreeModel(top);
388         tree = new JTree(treeModel);
389 
390         tree.setCellRenderer(new ScriptTreeRenderer());
391 
392         tree.getSelectionModel().setSelectionMode
393             (TreeSelectionModel.SINGLE_TREE_SELECTION);
394 
395         tree.addTreeSelectionListener(new TreeSelectionListener() {
396             public void valueChanged(TreeSelectionEvent e) {
397                 XBrowseNode xbn = getSelection();
398                 XPropertySet props = (XPropertySet)UnoRuntime.queryInterface(
399                     XPropertySet.class, xbn);
400 
401                 if (xbn == null) {
402                     textField.setText("");
403                     return;
404                 }
405 
406                 String str = xbn.getName();
407                 if (xbn.getType() == BrowseNodeTypes.SCRIPT && props != null)
408                 {
409                     try {
410                         str = AnyConverter.toString(
411                             props.getPropertyValue("URI"));
412                     }
413                     catch (Exception ignore) {
414                         // default will be used
415                     }
416                 }
417                 textField.setText(str);
418             }
419         });
420 
421         JScrollPane scroller = new JScrollPane(tree);
422         add(scroller, BorderLayout.CENTER);
423 
424         textField = new JTextField();
425         add(textField, BorderLayout.SOUTH);
426     }
427 
removeNode(DefaultMutableTreeNode node)428     public void removeNode(DefaultMutableTreeNode node) {
429         MutableTreeNode parent = (MutableTreeNode)(node.getParent());
430         if (parent != null) {
431             treeModel.removeNodeFromParent(node);
432         }
433     }
434 
addNode(DefaultMutableTreeNode parent, XBrowseNode xbn)435     public void addNode(DefaultMutableTreeNode parent, XBrowseNode xbn) {
436         DefaultMutableTreeNode newNode =
437             new DefaultMutableTreeNode(xbn) {
438                 public String toString() {
439                     return ((XBrowseNode)getUserObject()).getName();
440                 }
441             };
442 
443         treeModel.insertNodeInto(newNode, parent, parent.getChildCount());
444         tree.scrollPathToVisible(new TreePath(newNode.getPath()));
445     }
446 
initNodes(XBrowseNode parent, DefaultMutableTreeNode top)447     private void initNodes(XBrowseNode parent, DefaultMutableTreeNode top) {
448         if ( parent == null || parent.hasChildNodes() == false )
449         {
450             return;
451         }
452 
453         XBrowseNode[] children = parent.getChildNodes();
454 
455         try {
456             if (children != null) {
457                 for (int i = 0; i < children.length; i++) {
458                     if ( children[i] == null )
459                     {
460                         continue;
461                     }
462                     DefaultMutableTreeNode newNode =
463                         new DefaultMutableTreeNode(children[i]) {
464                             public String toString() {
465                                 return ((XBrowseNode)getUserObject()).getName();
466                             }
467                         };
468                     top.add(newNode);
469                     initNodes(children[i], newNode);
470                 }
471             }
472         }
473         catch (java.lang.Exception e) {
474             e.printStackTrace();
475         }
476     }
477 }
478 
479 class ScriptTreeRenderer extends DefaultTreeCellRenderer {
480 
481     private ImageIcon sofficeIcon;
482     private ImageIcon scriptIcon;
483     private ImageIcon containerIcon;
484 
ScriptTreeRenderer()485     public ScriptTreeRenderer() {
486         sofficeIcon = new ImageIcon(getClass().getResource("soffice.gif"));
487         scriptIcon = new ImageIcon(getClass().getResource("script.gif"));
488         containerIcon = new ImageIcon(getClass().getResource("container.gif"));
489     }
490 
getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus)491     public Component getTreeCellRendererComponent(
492                         JTree tree,
493                         Object value,
494                         boolean sel,
495                         boolean expanded,
496                         boolean leaf,
497                         int row,
498                         boolean hasFocus) {
499 
500         super.getTreeCellRendererComponent(
501                         tree, value, sel,
502                         expanded, leaf, row,
503                         hasFocus);
504 
505         DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
506         XBrowseNode xbn = (XBrowseNode)node.getUserObject();
507         if (xbn.getType() == BrowseNodeTypes.SCRIPT) {
508             setIcon(scriptIcon);
509         }
510         else if(xbn.getType() == BrowseNodeTypes.CONTAINER) {
511             setIcon(containerIcon);
512         }
513         else if(xbn.getType() == BrowseNodeTypes.ROOT) {
514             setIcon(sofficeIcon);
515         }
516 
517         return this;
518     }
519 }
520