diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java new file mode 100644 index 000000000..0ab265ecc --- /dev/null +++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java @@ -0,0 +1,400 @@ +/* + * 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 com.sun.star.script.framework.provider.beanshell; + +import com.sun.star.script.framework.container.ScriptMetaData; +import com.sun.star.script.framework.provider.ClassLoaderFactory; +import com.sun.star.script.framework.provider.ScriptEditorBase; +import com.sun.star.script.framework.provider.SwingInvocation; +import com.sun.star.script.provider.XScriptContext; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.Dimension; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.net.URL; + +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import javax.swing.JToolBar; +import javax.swing.BorderFactory; + +public class ScriptEditorForBeanShell extends ScriptEditorBase implements ActionListener { + + private JFrame frame; + private String filename; + + private ScriptSourceModel model; + private ScriptSourceView view; + + private URL scriptURL = null; + private ClassLoader cl = null; + private JButton saveBtn; + + // global ScriptEditorForBeanShell returned for getEditor() calls + private static ScriptEditorForBeanShell theScriptEditorForBeanShell; + + // global list of ScriptEditors, key is [external form of URL] of file being edited + private static Map<String, ScriptEditorForBeanShell> BEING_EDITED = + new HashMap<String, ScriptEditorForBeanShell>(); + + // template for new BeanShell scripts + private static String BSHTEMPLATE; + + // try to load the template for BeanShell scripts + static { + BSHTEMPLATE = "// BeanShell script"; + try { + URL url = ScriptEditorForBeanShell.class.getResource("template.bsh"); + if (url != null) { + InputStream in = url.openStream(); + StringBuilder buf = new StringBuilder(); + byte[] b = new byte[1024]; + int len; + + while ((len = in.read(b)) != -1) { + buf.append(new String(b, 0, len)); + } + + in.close(); + + BSHTEMPLATE = buf.toString(); + } + } catch (IOException ioe) { + } catch (Exception e) { + } + } + + /** + * Returns the global ScriptEditorForBeanShell instance. + */ + + public static synchronized ScriptEditorForBeanShell getEditor() { + if (theScriptEditorForBeanShell == null) { + theScriptEditorForBeanShell = + new ScriptEditorForBeanShell(); + } + + return theScriptEditorForBeanShell; + } + + /** + * Get the ScriptEditorForBeanShell instance for this URL + * + * @param url The URL of the script source file + * + * @return The ScriptEditorForBeanShell associated with + * the given URL if one exists, otherwise null. + */ + public static ScriptEditorForBeanShell getEditor(URL url) { + synchronized (BEING_EDITED) { + return BEING_EDITED.get(url.toExternalForm()); + } + } + + /** + * Returns whether or not the script source being edited in this + * ScriptEditorForBeanShell has been modified + */ + public boolean isModified() { + return view.isModified(); + } + + /** + * Returns the text being displayed in this ScriptEditorForBeanShell + * + * @return The text displayed in this ScriptEditorForBeanShell + */ + public String getText() { + return view.getText(); + } + + /** + * Returns the template text for BeanShell scripts + * + * @return The template text for BeanShell scripts + */ + public String getTemplate() { + return BSHTEMPLATE; + } + + /** + * Returns the default extension for BeanShell scripts + * + * @return The default extension for BeanShell scripts + */ + public String getExtension() { + return "bsh"; + } + + /** + * Indicates the line where error occurred + * + */ + public void indicateErrorLine(int lineNum) { + model.indicateErrorLine(lineNum); + } + + /** + * Executes the script edited by the editor + * + */ + public Object execute() throws Exception { + if (!isMacroExecutionEnabled()) { + showErrorMessage("Macro Execution has been disabled."); + return null; + } + + frame.toFront(); + return model.execute(context, cl); + } + + /** + * Opens an editor window for the specified ScriptMetaData. + * If an editor window is already open for that data it will be + * moved to the front. + * + * @param context The context in which to execute the script + * @param entry The metadata describing the script + */ + public void edit(final XScriptContext context, ScriptMetaData entry) { + if (entry != null) { + try { + ClassLoader cl = null; + + try { + cl = ClassLoaderFactory.getURLClassLoader(entry); + } catch (Exception ignore) { // TODO re-examine error handling + } + + final ClassLoader theCl = cl; + final URL url = entry.getSourceURL(); + SwingInvocation.invoke( + new Runnable() { + public void run() { + ScriptEditorForBeanShell editor; + + synchronized (BEING_EDITED) { + editor = BEING_EDITED.get(url.toExternalForm()); + + if (editor == null) { + editor = new ScriptEditorForBeanShell( + context, theCl, url); + BEING_EDITED.put(url.toExternalForm(), editor); + } + } + + editor.frame.toFront(); + } + }); + } catch (IOException ioe) { + showErrorMessage("Error loading file: " + ioe.getMessage()); + } + } + } + + private ScriptEditorForBeanShell() { + } + + private ScriptEditorForBeanShell(XScriptContext context, ClassLoader cl, + URL url) { + setContext(context); + this.scriptURL = url; + this.model = new ScriptSourceModel(url); + this.filename = ScriptMetaData.getFileName(url); + this.cl = cl; + + try { + + Class<?> c = + Class.forName("org.openoffice.netbeans.editor.NetBeansSourceView"); + + Class<?>[] types = new Class[] { ScriptSourceModel.class }; + + java.lang.reflect.Constructor<?> ctor = c.getConstructor(types); + + if (ctor != null) { + Object[] args = new Object[] { this.model }; + this.view = (ScriptSourceView) ctor.newInstance(args); + } else { + this.view = new PlainSourceView(model); + } + } catch (java.lang.Error err) { + this.view = new PlainSourceView(model); + } catch (Exception e) { + this.view = new PlainSourceView(model); + } + + this.model.setView(this.view); + initUI(); + this.view.addListener(new UnsavedChangesListener() { + @Override + public void onUnsavedChanges(boolean isUnsaved) { + if(filename != null) { + // enable or disable save button depending on unsaved changes + saveBtn.setEnabled(isUnsaved); + } + } + }); + frame.setVisible(true); + } + + private void initUI() { + frame = new JFrame("BeanShell Debug Window: " + filename); + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + + frame.addWindowListener( + new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + doClose(); + } + } + ); + + String[] labels = {"Run", "Clear", "Save","Undo","Redo"}; + JToolBar toolbar = new JToolBar(); + toolbar.setRollover(true); + for (String label : labels) { + JButton b = new JButton(label); + b.setToolTipText(label); + b.addActionListener(this); + toolbar.add(b); + toolbar.addSeparator(); + + // disable save button on start + if (label.equals("Save")) { + b.setEnabled(false); + saveBtn = b; + } + } + + frame.getContentPane().add((JComponent)view, BorderLayout.CENTER); + frame.add(toolbar, BorderLayout.NORTH); + frame.pack(); + frame.setSize(590, 480); + frame.setLocation(300, 200); + frame.setMinimumSize(new Dimension(500, 300)); + } + + private void doClose() { + if (view.isModified()) { + + int result = JOptionPane.showConfirmDialog(frame, + "The script has been modified. Do you want to save the changes?"); + + if (result == JOptionPane.CANCEL_OPTION) { + // don't close the window, just return + return; + } else if (result == JOptionPane.YES_OPTION) { + boolean saveSuccess = saveTextArea(); + + if (!saveSuccess) { + return; + } + } + } + + frame.dispose(); + shutdown(); + } + + private boolean saveTextArea() { + boolean result = true; + + if (!view.isModified()) { + return true; + } + + OutputStream fos = null; + + try { + String s = view.getText(); + fos = scriptURL.openConnection().getOutputStream(); + + if (fos != null) { + fos.write(s.getBytes()); + } else { + showErrorMessage( + "Error saving script: Could not open stream for file"); + result = false; + } + + view.setModified(false); + } catch (IOException ioe) { + showErrorMessage("Error saving script: " + ioe.getMessage()); + result = false; + } catch (Exception e) { + showErrorMessage("Error saving script: " + e.getMessage()); + result = false; + } finally { + if (fos != null) { + try { + fos.flush(); + } catch (IOException ignore) { + } + try { + fos.close(); + } catch (IOException ignore) { + } + } + } + + return result; + } + + private void shutdown() { + synchronized (BEING_EDITED) { + BEING_EDITED.remove(scriptURL.toExternalForm()); + } + } + + public void actionPerformed(ActionEvent e) { + String actionCommand = e.getActionCommand(); + if (actionCommand.equals("Run")) { + try { + execute(); + } catch (Exception invokeException) { + showErrorMessage(invokeException.toString()); + } + } else if (actionCommand.equals("Save")) { + saveTextArea(); + } else if (actionCommand.equals("Clear")) { + view.clear(); + } else if(actionCommand.equals("Undo")){ + view.undo(); + } else if(actionCommand.equals("Redo")){ + view.redo(); + } + } +} |