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