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 67 public ScriptSelector() 68 { 69 } 70 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 230 public void showOrganizer(final XScriptContext ctxt, 231 final com.sun.star.awt.MouseEvent e) 232 { 233 showOrganizer(ctxt); 234 } 235 236 public void showOrganizer(final XScriptContext ctxt, 237 final com.sun.star.awt.ActionEvent e) 238 { 239 showOrganizer(ctxt); 240 } 241 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 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 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 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 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 360 public ScriptSelectorPanel(XBrowseNode root) 361 { 362 this.myrootnode = root; 363 initUI(); 364 } 365 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 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 428 public void removeNode(DefaultMutableTreeNode node) { 429 MutableTreeNode parent = (MutableTreeNode)(node.getParent()); 430 if (parent != null) { 431 treeModel.removeNodeFromParent(node); 432 } 433 } 434 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 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 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 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