/* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ package org.libreoffice.example.java_scripts; import javax.swing.*; import javax.swing.tree.*; import javax.swing.table.*; import javax.swing.event.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.beans.*; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.Exception; import com.sun.star.uno.Any; import com.sun.star.uno.AnyConverter; import com.sun.star.uno.Type; import com.sun.star.uno.XComponentContext; import com.sun.star.lang.XMultiComponentFactory; import com.sun.star.lang.XComponent; import com.sun.star.frame.XModel; import com.sun.star.frame.FrameSearchFlag; import com.sun.star.frame.XDispatchProvider; import com.sun.star.frame.XDispatchHelper; import com.sun.star.frame.XDispatch; import com.sun.star.util.XURLTransformer; import com.sun.star.beans.*; import com.sun.star.script.XInvocation; import com.sun.star.lib.uno.helper.PropertySet; import com.sun.star.script.browse.XBrowseNode; import com.sun.star.script.browse.BrowseNodeTypes; import com.sun.star.script.browse.XBrowseNodeFactory; import com.sun.star.script.browse.BrowseNodeFactoryViewTypes; import com.sun.star.script.provider.XScriptContext; import com.sun.star.script.provider.XScript; import com.sun.star.script.provider.XScriptProvider; public class ScriptSelector { private static final int BIG_GAP = 10; private static final int MED_GAP = 5; private ScriptSelectorPanel selectorPanel; public ScriptSelector() { } public void showOrganizer(final XScriptContext ctxt) { try { XBrowseNode root = getRootNode(ctxt); final XScriptProvider msp = (XScriptProvider)UnoRuntime.queryInterface( XScriptProvider.class, root); final JFrame client = new JFrame("Script"); selectorPanel = new ScriptSelectorPanel(root); final JButton runButton, closeButton, createButton, editButton, deleteButton; runButton = new JButton("Run"); runButton.setEnabled(false); closeButton = new JButton("Close"); editButton = new JButton("Edit"); editButton.setEnabled(false); JPanel northButtons = new JPanel(new GridLayout(2, 1, MED_GAP, MED_GAP)); northButtons.add(runButton); northButtons.add(closeButton); createButton = new JButton("Create"); createButton.setEnabled(false); deleteButton = new JButton("Delete"); deleteButton.setEnabled(false); JPanel southButtons = new JPanel(new GridLayout(3, 1, MED_GAP, MED_GAP)); southButtons.add(editButton); southButtons.add(createButton); southButtons.add(deleteButton); selectorPanel.tree.addTreeSelectionListener( new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { XBrowseNode xbn = selectorPanel.getSelection(); XPropertySet props = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xbn); checkEnabled(props, "Creatable", createButton); checkEnabled(props, "Deletable", deleteButton); checkEnabled(props, "Editable", editButton); if (xbn != null && xbn.getType() == BrowseNodeTypes.SCRIPT) { runButton.setEnabled(true); } else { runButton.setEnabled(false); } } } ); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { if (event.getSource() == runButton) { String uri = selectorPanel.textField.getText(); try { XScript script = msp.getScript(uri); Object[][] out = new Object[1][0]; out[0] = new Object[0]; short[][] num = new short[1][0]; num[0] = new short[0]; script.invoke(new Object[0], num, out); } catch (Exception e) { e.printStackTrace(); } } else if (event.getSource() == closeButton) { client.dispose(); } else if (event.getSource() == editButton) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectorPanel.tree.getLastSelectedPathComponent(); if (node == null) return; showEditor(ctxt, node); } else if (event.getSource() == createButton) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectorPanel.tree.getLastSelectedPathComponent(); if (node == null) return; doCreate(ctxt, node); } else if (event.getSource() == deleteButton) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectorPanel.tree.getLastSelectedPathComponent(); if (node == null) return; doDelete(ctxt, node); } } }; runButton.addActionListener(listener); closeButton.addActionListener(listener); createButton.addActionListener(listener); editButton.addActionListener(listener); deleteButton.addActionListener(listener); JPanel buttonPanel = new JPanel(new BorderLayout()); buttonPanel.add(northButtons, BorderLayout.NORTH); buttonPanel.add(southButtons, BorderLayout.SOUTH); JPanel mainPanel = new JPanel(new BorderLayout(MED_GAP, MED_GAP)); mainPanel.setBorder( new EmptyBorder(BIG_GAP, BIG_GAP, BIG_GAP, BIG_GAP)); mainPanel.add(selectorPanel, BorderLayout.CENTER); mainPanel.add(buttonPanel, BorderLayout.EAST); client.getContentPane().add(mainPanel); client.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); client.setSize(500, 350); // set the x and y locations so that the frame is in the // centre of the screen Dimension d = client.getToolkit().getScreenSize(); int x = (int)((d.getWidth() - client.getWidth()) / 2); int y = (int)((d.getHeight() - client.getHeight()) / 2); client.setLocation(x, y); client.show(); } catch (com.sun.star.uno.RuntimeException rue) { rue.printStackTrace(); } catch (java.lang.Exception e) { e.printStackTrace(); } } public void showOrganizer(final XScriptContext ctxt, final com.sun.star.awt.MouseEvent e) { showOrganizer(ctxt); } public void showOrganizer(final XScriptContext ctxt, final com.sun.star.awt.ActionEvent e) { showOrganizer(ctxt); } private void doDelete( XScriptContext ctxt, DefaultMutableTreeNode node) { Object obj = node.getUserObject(); XInvocation inv = (XInvocation)UnoRuntime.queryInterface( XInvocation.class, obj); Object[] args = new Object[] { ctxt }; try { Object result = inv.invoke("Deletable", args, new short[1][0], new Object[1][0]); if (result != null && AnyConverter.toBoolean(result) == true) { selectorPanel.removeNode(node); } } catch (Exception e) { e.printStackTrace(); } } private void doCreate( XScriptContext ctxt, DefaultMutableTreeNode node) { Object obj = node.getUserObject(); XInvocation inv = (XInvocation)UnoRuntime.queryInterface( XInvocation.class, obj); Object[] args = new Object[] { ctxt }; try { Object result = inv.invoke("Creatable", args, new short[1][0], new Object[1][0]); if (result != null) { XBrowseNode xbn = (XBrowseNode) AnyConverter.toObject(new Type(XBrowseNode.class), result); selectorPanel.addNode(node, xbn); } } catch (Exception e) { e.printStackTrace(); } } private void showEditor( XScriptContext ctxt, DefaultMutableTreeNode node) { Object obj = node.getUserObject(); XInvocation inv = (XInvocation)UnoRuntime.queryInterface( XInvocation.class, obj); Object[] args = new Object[] { ctxt }; try { inv.invoke("Editable", args, new short[1][0], new Object[1][0]); } catch (Exception e) { e.printStackTrace(); } } private void checkEnabled(XPropertySet props, String name, JButton button) { boolean enable = false; try { if (props != null) { Object o = props.getPropertyValue(name); enable = AnyConverter.toBoolean( props.getPropertyValue(name)); } } catch (com.sun.star.lang.IllegalArgumentException iae) { // leave enable set to false } catch (com.sun.star.beans.UnknownPropertyException upe) { // leave enable set to false } catch (com.sun.star.lang.WrappedTargetException wte) { // leave enable set to false } button.setEnabled(enable); } private XBrowseNode getRootNode(XScriptContext ctxt) { XBrowseNode result = null; XComponentContext xcc = ctxt.getComponentContext(); XMultiComponentFactory xmcf = xcc.getServiceManager(); XBrowseNodeFactory xBrowseFac = (XBrowseNodeFactory) UnoRuntime.queryInterface(XBrowseNodeFactory.class, xcc.getValueByName( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory")); result = (XBrowseNode)UnoRuntime.queryInterface( XBrowseNode.class, xBrowseFac.createView( BrowseNodeFactoryViewTypes.MACROORGANIZER)); return result; } } class ScriptSelectorPanel extends JPanel { private XBrowseNode myrootnode = null; public JTextField textField; public JTree tree; public DefaultTreeModel treeModel; public ScriptSelectorPanel(XBrowseNode root) { this.myrootnode = root; initUI(); } public XBrowseNode getSelection() { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if (node == null) { return null; } return (XBrowseNode)node.getUserObject(); } private void initUI() { setLayout(new BorderLayout()); DefaultMutableTreeNode top = new DefaultMutableTreeNode(myrootnode) { public String toString() { return ((XBrowseNode)getUserObject()).getName(); } }; initNodes(myrootnode, top); treeModel = new DefaultTreeModel(top); tree = new JTree(treeModel); tree.setCellRenderer(new ScriptTreeRenderer()); tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { XBrowseNode xbn = getSelection(); XPropertySet props = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, xbn); if (xbn == null) { textField.setText(""); return; } String str = xbn.getName(); if (xbn.getType() == BrowseNodeTypes.SCRIPT && props != null) { try { str = AnyConverter.toString( props.getPropertyValue("URI")); } catch (Exception ignore) { // default will be used } } textField.setText(str); } }); JScrollPane scroller = new JScrollPane(tree); add(scroller, BorderLayout.CENTER); textField = new JTextField(); add(textField, BorderLayout.SOUTH); } public void removeNode(DefaultMutableTreeNode node) { MutableTreeNode parent = (MutableTreeNode)(node.getParent()); if (parent != null) { treeModel.removeNodeFromParent(node); } } public void addNode(DefaultMutableTreeNode parent, XBrowseNode xbn) { DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(xbn) { public String toString() { return ((XBrowseNode)getUserObject()).getName(); } }; treeModel.insertNodeInto(newNode, parent, parent.getChildCount()); tree.scrollPathToVisible(new TreePath(newNode.getPath())); } private void initNodes(XBrowseNode parent, DefaultMutableTreeNode top) { if (parent == null || parent.hasChildNodes() == false) { return; } XBrowseNode[] children = parent.getChildNodes(); try { if (children != null) { for (int i = 0; i < children.length; i++) { if (children[i] == null) { continue; } DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(children[i]) { public String toString() { return ((XBrowseNode)getUserObject()).getName(); } }; top.add(newNode); initNodes(children[i], newNode); } } } catch (java.lang.Exception e) { e.printStackTrace(); } } } class ScriptTreeRenderer extends DefaultTreeCellRenderer { private ImageIcon sofficeIcon; private ImageIcon scriptIcon; private ImageIcon containerIcon; public ScriptTreeRenderer() { sofficeIcon = new ImageIcon(getClass().getResource("soffice.gif")); scriptIcon = new ImageIcon(getClass().getResource("script.gif")); containerIcon = new ImageIcon(getClass().getResource("container.gif")); } public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus); DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; XBrowseNode xbn = (XBrowseNode)node.getUserObject(); if (xbn.getType() == BrowseNodeTypes.SCRIPT) { setIcon(scriptIcon); } else if (xbn.getType() == BrowseNodeTypes.CONTAINER) { setIcon(containerIcon); } else if (xbn.getType() == BrowseNodeTypes.ROOT) { setIcon(sofficeIcon); } return this; } }