This does not happen when I execute Python macro from menu item. I wrote a toy, alternative script organizer dialog for Python.
Code: Select all
import uno
import unohelper
import traceback
import sys
try:
import pythonscript
except:
import pythonloader
pythonscript = None
for url, module in pythonloader.g_loadedComponents.iteritems():
if url.endswith("script-provider-for-python/pythonscript.py"):
pythonscript = module
if pythonscript is None:
raise Exception("Failed to find pythonscript module.")
from com.sun.star.awt import XActionListener, XMouseListener, \
XKeyListener, Rectangle, Selection
from com.sun.star.awt.tree import XTreeExpansionListener
from com.sun.star.uno import Exception as UNOException
# Default content of the new file.
TEMPLATE = """"""
class DialogBase(object):
""" Base class for dialog. """
def __init__(self, ctx):
self.ctx = ctx
def create(self, name):
""" Create service instance. """
return self.ctx.getServiceManager().createInstanceWithContext(
name, self.ctx)
class RuntimeDialogBase(DialogBase):
""" Runtime dialog base. """
def __init__(self, ctx):
DialogBase.__init__(self, ctx)
self.dialog = None
def _result(self):
""" Returns result. """
return None
def _init(self):
""" Initialize, create dialog and controls. """
def execute(self):
""" Execute to show this dialog.
None return value should mean canceled.
"""
self._init()
result = None
self.dialog.setVisible(True)
if self.dialog.execute():
result = self._result()
self.dialog.dispose()
return result
def create_control(self, name, type, pos, size,
prop_names, prop_values, full_name=False):
""" Create and insert control. """
if not full_name:
type = "com.sun.star.awt.UnoControl" + type + "Model"
dialog_model = self.dialog.getModel()
model = dialog_model.createInstance(type)
if prop_names and prop_values:
model.setPropertyValues(prop_names, prop_values)
dialog_model.insertByName(name, model)
ctrl = self.dialog.getControl(name)
ctrl.setPosSize(pos[0], pos[1], size[0], size[1], 15)
return ctrl
def create_dialog(self, title, pos=None, size=None, parent=None):
""" Create base dialog. """
dialog = self.create("com.sun.star.awt.UnoControlDialog")
dialog_model = self.create("com.sun.star.awt.UnoControlDialogModel")
dialog.setModel(dialog_model)
if isinstance(size, tuple) and len(size) == 2:
dialog.setPosSize(0, 0, size[0], size[1], 12)
if isinstance(pos, tuple) and len(pos) == 2:
dialog.setPosSize(pos[0], pos[1], 0, 0, 3)
elif parent:
pass
dialog.setTitle(title)
self.dialog = dialog
def create_label(self, name, command, pos, size,
prop_names=None, prop_values=None, action=None):
""" Create and add new label. """
label = self.create_control(name, "Label", pos, size,
prop_names, prop_values)
def create_button(self, name, command, pos, size,
prop_names=None, prop_values=None, action=None):
""" Create and add new button. """
btn = self.create_control(name, "Button", pos, size,
prop_names, prop_values)
btn.setActionCommand(command)
if action:
btn.addActionListener(action)
def create_edit(self, name, pos, size,
prop_names=None, prop_values=None):
""" Create and add new edit control. """
edit = self.create_control(name, "Edit", pos, size,
prop_names, prop_values)
def create_tree(self, name, pos, size,
prop_names=None, prop_values=None):
""" Create and add new tree. """
self.create_control(name,
"com.sun.star.awt.tree.TreeControlModel",
pos, size, prop_names, prop_values, full_name=True)
def get(self, name):
""" Returns specified control by name. """
return self.dialog.getControl(name)
def get_text(self, name):
""" Returns value of Text attribute specified by name. """
return self.dialog.getControl(name).getModel().Text
def set_focus(self, name):
""" Set focus to the control specified by the name. """
self.dialog.getControl(name).setFocus()
class NameInput(RuntimeDialogBase):
""" Input dialog. """
MARGIN = 3
BUTTON_WIDTH = 80
BUTTON_HEIGHT = 26
HEIGHT = MARGIN * 3 + BUTTON_HEIGHT * 2
WIDTH = 300
EDIT_NAME = "edit_name"
def __init__(self, ctx, title, default="", parent=None):
RuntimeDialogBase.__init__(self, ctx)
self.title = title
self.default = default
self.parent = parent
def _init(self):
margin = self.MARGIN
self.create_dialog(self.title, size=(self.WIDTH, self.HEIGHT))
self.create_edit(self.EDIT_NAME,
pos=(margin, margin),
size=(self.WIDTH - margin * 2, self.BUTTON_HEIGHT),
prop_names=("HideInactiveSelection", "Text",),
prop_values=(True, self.default,))
self.create_button("btn_ok", "ok",
pos=(self.WIDTH - self.BUTTON_WIDTH * 2 - margin * 2,
self.BUTTON_HEIGHT + margin * 2),
size=(self.BUTTON_WIDTH, self.BUTTON_HEIGHT),
prop_names=("DefaultButton", "Label", "PushButtonType",),
prop_values=(True, "OK", 1))
self.create_button("btn_cancel", "cancel",
pos=(self.WIDTH - self.BUTTON_WIDTH - margin,
self.BUTTON_HEIGHT + margin * 2),
size=(self.BUTTON_WIDTH, self.BUTTON_HEIGHT),
prop_names=("Label", "PushButtonType"), prop_values=("Cancel", 2))
self.set_focus(self.EDIT_NAME)
if self.parent:
self.dialog.createPeer(self.parent.getToolkit(), self.parent)
if self.default:
self.get(self.EDIT_NAME).setSelection(Selection(0, len(self.default)))
def _result(self):
return self.get_text("edit_name")
class FileOpenDialog(DialogBase):
""" To get file url to open. """
def __init__(self, ctx, **kwds):
DialogBase.__init__(self, ctx)
self.args = kwds
def execute(self):
fp = self.create("com.sun.star.ui.dialogs.FilePicker")
args = self.args
if "title" in args:
fp.setTitle(args["title"])
if "default" in args:
default = args["default"]
fp.setDefaultName(self._substitute_variables(default))
if "directory" in args:
fp.setDisplayDirectory(args["directory"])
if "filters" in args:
for title, filter in args["filters"]:
fp.appendFilter(title, filter)
result = None
if fp.execute():
result = fp.getFiles()[0]
return result
def _substitute_variables(self, uri):
return self.create("com.sun.star.util.PathSubstitution").\
substituteVariables(uri, True)
class MessageDialog(DialogBase):
""" Shows message in standard message box. """
def __init__(self, ctx, parent, **kwds):
DialogBase.__init__(self, ctx)
self.parent = parent
self.args = kwds
def execute(self):
args = self.args
type = args.get("type", "messbox")
buttons = args.get("buttons", 1)
title = args.get("title", "")
message = args.get("message", "")
toolkit = self.parent.getToolkit()
dialog = toolkit.createMessageBox(
self.parent, Rectangle(), type, buttons, title, message)
n = dialog.execute()
dialog.dispose()
return n
def join_url(base, name, name_encode=True):
""" Join name to base URL. """
if name_encode:
_name = name
else:
_name = unohelper.systemPathToFileUrl(name)
if base.endswith("/"):
return base + _name
return base + "/" + _name
def base_url(url):
""" Returns directory of URL. """
if url.startswith( OrganizerDialog.DOC_PROTOCOL):
return "/".join(url.split("/")[:-1])
else:
return unohelper.absolutize(url, "../")
class ErrorMessageDialog(RuntimeDialogBase):
""" Shows error message in custom dialog with selectable text. """
MARGIN = 3
BUTTON_WIDTH = 80
BUTTON_HEIGHT = 26
EDIT_HEIGHT = 300
HEIGHT = EDIT_HEIGHT + MARGIN * 5 + BUTTON_HEIGHT + MARGIN
WIDTH = 420
EDIT_NAME = "edit_name"
ERROR_ICON = "private:standardimage/error"
def __init__(self, ctx, **kwds):
RuntimeDialogBase.__init__(self, ctx)
self.args = kwds
def _init(self):
args = self.args
title = args.get("title", "")
message = args.get("message", "")
margin = self.MARGIN
self.create_dialog(title, size=(self.WIDTH, self.HEIGHT))
self.create_edit("edit_message",
pos=(margin * 4, margin * 4),
size=(self.WIDTH - margin * 8, self.EDIT_HEIGHT),
prop_names=("Border", "MultiLine", "PaintTransparent",
"ReadOnly", "VScroll"),
prop_values=(0, True, True, True, True))
self.get("edit_message").getModel().Text = message
self.create_button("btn_ok", "ok",
pos=((self.WIDTH - self.BUTTON_WIDTH)/2,
self.HEIGHT - self.BUTTON_HEIGHT - margin),
size=(self.BUTTON_WIDTH, self.BUTTON_HEIGHT),
prop_names=("DefaultButton", "Label", "PushButtonType",),
prop_values=(True, "OK", 1))
class ErrorAsMessage(Exception):
""" Tracked error message will be shown for user. """
pass
class NodeManager(object):
""" Maps between tree node and script node. """
LOADED = 0x100000
SCRIPT = 0x700000
MASK = 0xfffff
TYPE_MASK = 0xf00000
def __init__(self):
self.nodes = [] # to avoid adapter creation for each node
def _node_set(self, tree_node, node, script=False):
""" Set script node for tree_node. """
self.nodes.append(node)
i = len(self.nodes) -1
if script:
i |= self.SCRIPT
tree_node.DataValue = i
def _node_get(self, tree_node):
""" Get script node for tree_node. """
try:
i = tree_node.DataValue
if isinstance(i, int) or isinstance(i, long):
return self.nodes[i & self.MASK]
except:
pass
def _node_delete(self, tree_node):
""" Delete script node for tree_node. """
try:
i = tree_node.DataValue
if isinstance(i, int):
node = self.nodes[i & sel.MASK]
self.nodes[i] = None
except:
pass
def _node_is_script(self, tree_node):
""" Check the node is script for tree_node. """
return (tree_node.DataValue & self.TYPE_MASK) == self.SCRIPT
def _node_set_loaded(self, tree_node):
""" Set loaded flag. """
tree_node.DataValue = tree_node.DataValue | self.LOADED
def _node_is_loaded(self, tree_node):
""" Check loaded flag. """
return (tree_node.DataValue & self.TYPE_MASK) == self.LOADED
class OrganizerDialog(NodeManager, RuntimeDialogBase):
""" Alternative organizer dialog for Python scripts. """
TITLE = "Python Scripts"
TREE_NAME = "tree"
FILE_EXT = ".py"
DOC_PROTOCOL = "vnd.sun.star.tdoc"
SCRIPT_PROTOCOL = "vnd.sun.star.script"
DEFAULT_NAME = "macro"
DISK_ICON = "private:graphicrepository/res/harddisk_16.png"
DOC_ICON = "private:graphicrepository/res/sx03150.png"
DIR_ICON = "private:graphicrepository/res/fileopen.png"
FILE_ICON = "private:graphicrepository/res/im30820.png"
SCRIPT_ICON = "private:graphicrepository/res/im30821.png"
MARGIN = 3
BUTTON_WIDTH = 80
BUTTON_HEIGHT = 26
TREE_HEIGHT = 250
HEIGHT = TREE_HEIGHT + BUTTON_HEIGHT + MARGIN * 3
WIDTH = 300
ENABLE_EDIT = False
ENABLE_DEBUG = False
def __init__(self, ctx,
user_provider, share_provider, document_provider,
parent, show_icon=False):
NodeManager.__init__(self)
RuntimeDialogBase.__init__(self, ctx)
self.parent = parent
self.user_provider = user_provider
self.share_provider = share_provider
self.document_provider = document_provider
self.show_icon = show_icon
self.tree = None
self.menu = None
def execute(self, history=None):
""" Show dialog with history representes script in URI form. """
self._create_ui()
self._set_history(history)
result = None
self.dialog.setVisible(True)
n = self.dialog.execute()
if n:
result = self.tree_get_selected_node_uri()
self.tree = None
self.dialog.dispose()
return result
def button_pushed(self, command):
try:
tree_node = self.tree_get_selected_node()
if tree_node:
node = self._node_get(tree_node)
getattr(self, "exec_" + command)(tree_node, node)
except ErrorAsMessage, e:
MessageDialog(self.ctx, self.dialog.getPeer(),
type="errorbox", title="Error", message=str(e)).execute()
except Exception, e:
print(e)
traceback.print_exc()
def exec_execute(self, tree_node, node):
""" Execute selected macro. """
if self._node_is_script(tree_node):
self.dialog.endDialog(1)
def exec_menu(self, tree_node, node):
""" Shows dropdown menu. """
if not self.menu:
self._create_menu()
menu = self.menu
if tree_node:
if isinstance(node, pythonscript.ScriptBrowseNode):
states = (False, False, self.ENABLE_EDIT, False,
False, True, self.ENABLE_DEBUG)
elif isinstance(node, pythonscript.FileBrowseNode):
states = [False, False, self.ENABLE_EDIT, False,
True, True, False]
if node.uri.startswith(self.DOC_PROTOCOL):
states[3] = True
elif isinstance(node, pythonscript.DirBrowseNode):
states = (True, True, False, False, True, True, False)
else:
states = (True, True, False, False, False, False, False)
for i, state in enumerate(states):
menu.enableItem(i +1, state)
btn = self.dialog.getControl("btn_menu")
n = menu.execute(
btn.getContext().getPeer(), btn.getPosSize(), 0)
if n > 0:
self.button_pushed(menu.getCommand(n))
def exec_create_file(self, tree_node, node):
""" Create new file under selected node. """
if isinstance(node, pythonscript.PythonScriptProvider):
_node = node
node = node.dirBrowseNode
elif not isinstance(node, pythonscript.DirBrowseNode):
return
name = self._input_name("New File Name")
if not name is None and not name == "":
uri = join_url(node.rootUrl, name)
if not uri.endswith(self.FILE_EXT):
uri += self.FILE_EXT
sfa = node.provCtx.sfa
if sfa.exists(uri):
raise ErrorAsMessage("File already exists: \n" + name)
is_doc = uri.startswith(self.DOC_PROTOCOL)
try:
if is_doc:
io = self.create("com.sun.star.io.Pipe")
else:
io = sfa.openFileWrite(uri)
except Exception, e:
raise ErrorAsMessage(str(e))
try:
if TEMPLATE or is_doc:
text_out = self.create(
"com.sun.star.io.TextOutputStream")
text_out.setOutputStream(io)
text_out.setEncoding("UTF-8")
text_out.writeString(TEMPLATE)
if is_doc:
text_out.closeOutput()
sfa.writeFile(uri, io)
except Exception, e:
raise ErrorAsMessage(str(e))
finally:
if is_doc:
io.closeInput()
else:
io.closeOutput()
child_node = pythonscript.FileBrowseNode(
node.provCtx, uri, name)
self._create_new_tree_node(
tree_node, name, False, child_node)
def exec_create_dir(self, tree_node, node):
""" Create new directory under selected node. """
if isinstance(node, pythonscript.PythonScriptProvider):
_node = node
node = node.dirBrowseNode
elif not isinstance(node, pythonscript.DirBrowseNode):
return
name = self._input_name("New Directory Name", default="directory")
if not name is None and not name == "":
uri = join_url(node.rootUrl, name)
sfa = node.provCtx.sfa
if sfa.exists(uri):
raise ErrorAsMessage("Directory already exists: \n" + name)
try:
sfa.createFolder(uri)
child_node = pythonscript.DirBrowseNode(
node.provCtx, name, uri)
self._create_new_tree_node(
tree_node, name, False, child_node, True)
except Exception, e:
raise ErrorAsMessage(str(e))
def exec_substitute(self, tree_node, node):
""" Substitute script file in documents. """
if not isinstance(node, pythonscript.FileBrowseNode):
return
if not node.uri.startswith(self.DOC_PROTOCOL):
return
url = FileOpenDialog(self.ctx,
default="$(user)/Scripts/python",
filters=(("All Files (*.*)", "*.*"),
("Python Script (*.py)", "*.py"),)).execute()
if not url is None:
sfa = node.provCtx.sfa
if not sfa.exists(url):
raise ErrorAsMessage("File did not find: \n" + url)
try:
sfa.kill(node.uri)
sfa.copy(url, node.uri)
except Exception, e:
raise ErrorAsMessage(str(e))
def exec_rename(self, tree_node, node):
""" Rename selected file. """
if not (isinstance(node, pythonscript.FileBrowseNode) or \
isinstance(node, pythonscript.DirBrowseNode)):
return
current = node.getName()
name = self._input_name("Rename File", current)
if not name is None or not name == "":
if isinstance(node, pythonscript.FileBrowseNode):
uri = node.uri
elif isinstance(node, pythonscript.DirBrowseNode):
uri = node.rootUrl
new_uri = join_url(base_url(uri), name)
if not new_uri.endswith(self.FILE_EXT):
new_uri += self.FILE_EXT
sfa = node.provCtx.sfa
if not sfa.exists(uri):
raise ErrorAsMessage("Source file did not exist: \n" + current)
if sfa.exists(new_uri):
raise ErrorAsMessage("File exists: \n" + name)
try:
sfa.move(uri, new_uri)
tree_node.setDisplayValue(name)
node.name = name
except Exception, e:
raise ErrorAsMessage(str(e))
def exec_delete(self, tree_node, node):
""" Delete selected node. """
if not (isinstance(node, pythonscript.FileBrowseNode) or \
isinstance(node, pythonscript.DirBrowseNode)):
return
name = node.getName()
n = MessageDialog(self.ctx, self.dialog.getPeer(),
buttons=2, title="Delete File",
message="Do you want to delete file: \n" + name).execute()
if n == 1:
if isinstance(node, pythonscript.FileBrowseNode):
uri = node.uri
elif isinstance(node, pythonscript.DirBrowseNode):
uri = node.rootUrl
sfa = node.provCtx.sfa
try:
sfa.kill(uri)
self._node_delete(tree_node)
parent_node = tree_node.getParent()
parent_node.removeChildByIndex(
parent_node.getIndex(tree_node))
except Exception, e:
raise ErrorAsMessage(str(e))
def exec_edit(self, tree_node, node):
pass
def exec_debug(self, tree_node, node):
pass
class ListenerBase(unohelper.Base):
def __init__(self, act):
self.act = act
def disposing(self):
self.act = None
class ActionListener(ListenerBase, XActionListener):
def actionPerformed(self, ev):
self.act.button_pushed(ev.ActionCommand)
class KeyListener(ListenerBase, XKeyListener):
def keyPressed(self, ev): pass
def keyReleased(self, ev):
if ev.KeyCode == 1280:
self.act._key_pressed()
def _key_pressed(self):
node = self.tree_get_selected_node()
if node and self._node_is_script(node):
self.dialog.endDialog(1)
class MouseListener(ListenerBase, XMouseListener):
def mouseReleased(self, ev): pass
def mouseEntered(self, ev): pass
def mouseExited(self, ev): pass
def mousePressed(self, ev):
if ev.ClickCount == 2 and ev.Buttons == 1:
self.act._mouse_pressed(ev)
def _mouse_pressed(self, ev):
if ev.ClickCount == 2 and ev.Buttons == 1:
node = self.tree_get_selected_node()
if node and self._node_is_script(node):
self.dialog.endDialog(1)
class TreeExpansionListener(ListenerBase, XTreeExpansionListener):
def treeExpanding(self, ev): pass
def treeCollapsing(self, ev): pass
def treeExpanded(self, ev): pass
def treeCollapsed(self, ev): pass
def requestChildNodes(self, ev):
try:
node = ev.Node
if node:
self.act.node_requested(node)
except ErrorAsMessage, e:
MessageDialog(self.act.ctx, self.act.dialog.getPeer(),
type="errorbox", title="Error", message=str(e)).execute()
except Exception, e:
print(e)
traceback.print_exc()
def node_requested(self, tree_node):
""" Add children for the tree_node at expanding. """
data_model = self.tree.getModel().DataModel
node = self._node_get(tree_node)
try:
child_nodes = node.getChildNodes()
except Exception, e:
raise ErrorAsMessage(str(e))
if node and not tree_node.getChildCount() and child_nodes:
show_icon = self.show_icon
child_ondemand = True
is_script = False
if isinstance(node, pythonscript.ScriptBrowseNode):
return
elif isinstance(node, pythonscript.FileBrowseNode):
child_ondemand = False
is_script = True
nodes = [(child.getName(), child) for child in child_nodes]
for name, child in sorted(nodes):
tree_child = data_model.createNode(name, child_ondemand)
if show_icon:
if isinstance(child, pythonscript.ScriptBrowseNode):
icon = self.SCRIPT_ICON
elif isinstance(child, pythonscript.FileBrowseNode):
icon = self.FILE_ICON
elif isinstance(child, pythonscript.DirBrowseNode):
icon = self.DIR_ICON
else:
icon = self.FILE_ICON
self._set_node_icon(tree_child, icon)
tree_node.appendChild(tree_child)
self._node_set(tree_child, child, is_script)
self._node_set_loaded(tree_node)
def _input_name(self, title="", default=DEFAULT_NAME):
""" Let user input new name. """
return NameInput(self.ctx, title, default, self.dialog.getPeer()).execute()
def _set_history(self, history):
""" Show and select node by history. """
if history and history.startswith(self.SCRIPT_PROTOCOL):
parts = history[len(self.SCRIPT_PROTOCOL)+1:].split("?", 1)
if not len(parts) == 2 or parts[0].find("$") == -1:
return
params = parts[1].split("&")
if not "language=Python" in params:
return
location = None
for param in params:
if param.startswith("location="):
location = param[9:]
break
provider = None
if hasattr(self, location + "_provider"):
provider = getattr(self, location + "_provider")
if provider:
parent_node = self._get_tree_node(location)
self.node_requested(parent_node)
self._expand_node(parent_node)
path, func = parts[0].split("$", 1)
paths = path.split("|")
if paths[-1].endswith(self.FILE_EXT):
paths[-1] = paths[-1][:-len(self.FILE_EXT)]
paths.append(func)
tree_node = None
for path in paths:
for i in range(parent_node.getChildCount()):
tree_node = parent_node.getChildAt(i)
if tree_node.getDisplayValue() == \
uno.fileUrlToSystemPath(path):
parent_node = tree_node
self.node_requested(tree_node)
self._expand_node(parent_node)
break
if tree_node:
self.tree_select_node(tree_node)
def tree_get_selected_node(self):
""" Returns selected tree node. """
tree_node = self.tree.getSelection()
if not isinstance(tree_node, tuple):
return tree_node
return None
def tree_get_selected_node_uri(self):
""" Returns script uri if selected node is script node. """
tree_node = self.tree_get_selected_node()
if self._node_is_script(tree_node):
node = self._node_get(tree_node)
if node:
return node.getPropertyValue("URI")
def tree_select_node(self, tree_node):
""" Select tree node. """
self.tree.select(tree_node)
def _create_new_tree_node(self, tree_parent_node,
name, ondemand, node, directory=False, select=True):
""" Create new tree node under tree_parent_node. """
if not self._node_is_loaded(tree_parent_node):
self.node_requested(tree_parent_node)
return
tree_node = self.tree.getModel().DataModel.createNode(name, ondemand)
if self.show_icon:
if directory:
self._set_node_icon(tree_node, self.FILE_ICON)
else:
self._set_node_icon(tree_node, self.FILE_ICON)
tree_parent_node.appendChild(tree_node)
self._node_set(tree_node, node)
if select:
self.tree.select(tree_node)
def _create_menu(self):
""" Create popup menu. """
menu = self.create("com.sun.star.awt.PopupMenu")
menu.hideDisabledEntries(True)
self.menu = menu
items = (
(1, 0, 0, "Create File", "create_file"),
(2, 1, 0, "Create Directory", "create_dir"),
(None, 2),
(3, 3, 0, "Edit", "edit"),
(4, 4, 0, "Substitute", "substitute"),
(5, 5, 0, "Rename", "rename"),
(None, 6),
(6, 7, 0, "Delete", "delete"),
(None, 8),
(7, 9, 0, "Debug", "debug")
)
for i in items:
if i[0] is None or i[0] == -1:
menu.insertSeparator(i[1])
else:
menu.insertItem(i[0], i[3], i[2], i[1])
menu.setCommand(i[0], i[4])
def _set_node_icon(self, node, icon):
""" Set node icon. """
node.setExpandedGraphicURL(icon)
node.setCollapsedGraphicURL(icon)
def _expand_node(self, tree_node):
""" Request to expand node. """
self.tree.expandNode(tree_node)
def _get_tree_node(self, type):
tree_node = None
root_node = self.tree.getModel().DataModel.getRoot()
n = -1
if type == "user":
if self.user_provider:
n = 0
elif type == "share":
if self.share_provider:
n = 0
if self.user_provider:
n = 1
elif type == "document":
if self.document_provider:
n = 0
if self.user_provider:
n += 1
if self.share_provider:
n += 1
if n >= 0:
tree_node = root_node.getChildAt(n)
return tree_node
def _create_ui(self):
""" Create dialog ui. """
btn_action = self.ActionListener(self)
margin = self.MARGIN
btn_size = self.BUTTON_WIDTH, self.BUTTON_HEIGHT
btn_width, btn_height = btn_size
btn_prop_names = ("Label", "PushButtonType")
self.create_dialog(self.TITLE, size=(self.WIDTH, self.HEIGHT))
self.create_tree(self.TREE_NAME,
(margin, btn_height + margin * 2),
(self.WIDTH - 2 * margin, self.TREE_HEIGHT),
("Tabstop",), (True,))
self.create_button("btn_execute", "execute",
(margin, margin), btn_size,
btn_prop_names, ("Execute", 0), btn_action)
self.create_button("btn_menu", "menu",
(btn_width + margin * 2, margin), btn_size,
btn_prop_names, ("Menu", 0), btn_action)
self.create_button("btn_close", "",
(self.WIDTH - margin - btn_width, margin), btn_size,
btn_prop_names, ("Close", 2))
tree = self.dialog.getControl(self.TREE_NAME)
self.tree = tree
tree_model = tree.getModel()
data_model = self.create("com.sun.star.awt.tree.MutableTreeDataModel")
tree_model.DataModel = data_model
root = data_model.createNode("ROOT", False)
data_model.setRoot(root)
def add_node(name, provider, icon):
node = data_model.createNode(name, True)
if self.show_icon:
self._set_node_icon(node, icon)
root.appendChild(node)
self._node_set(node, provider)
if self.user_provider:
add_node("user", self.user_provider, self.DISK_ICON)
if self.share_provider:
add_node("share", self.share_provider, self.DISK_ICON)
if self.document_provider:
add_node("Document", self.document_provider, self.DOC_ICON)
tree_model.SelectionType = 1
tree_model.RootDisplayed = False
tree.addTreeExpansionListener(self.TreeExpansionListener(self))
tree.addMouseListener(self.MouseListener(self))
tree.addKeyListener(self.KeyListener(self))
tree.setFocus()
parent = self.parent
ps = parent.getPosSize()
self.dialog.setPosSize(
(ps.Width - self.WIDTH)/2, (ps.Height - self.HEIGHT)/2, 0, 0, 3)
self.dialog.createPeer(parent.getToolkit(), parent)
class PythonScriptOrganizer(object):
""" Alternative script organizer for Python scripting. """
History = None # URI of previous executed script
def __init__(self, ctx,
show_user=True, show_share=False, show_doc=True, show_icon=True):
self.ctx = ctx
self.show_icon = show_icon
self.show_user = show_user
self.show_share = show_share
self.doc = None
if show_doc:
self.doc = self._get_active_doc_uri()
self.user_sp = None
self.share_sp = None
self.document_sp = None
def _get_active_doc_uri(self):
""" Returns internal uri for the current document. """
doc = self._get_desktop().getCurrentComponent()
uri = self._get_document_uri(doc)
if uri:
return uri.rstrip("/")
def _get_desktop(self):
""" Returns desktop. """
return self.ctx.getServiceManager().createInstanceWithContext(
"com.sun.star.frame.Desktop", self.ctx)
def _get_active_frame(self):
""" Returns active frame. """
return self._get_desktop().ActiveFrame
def _store_history(self, result):
""" Store history. """
self.__class__.History = result
def _get_document_uri(self, doc):
""" Get document transient URI. """
tddc = self.ctx.getServiceManager().createInstanceWithContext(
"com.sun.star.frame.TransientDocumentsDocumentContentFactory", self.ctx)
try:
content = tddc.createDocumentContent(doc)
id = content.getIdentifier()
return id.getContentIdentifier()
except:
pass
def execute(self):
""" Show dialog. """
PythonScriptProvider = pythonscript.PythonScriptProvider
if self.show_user:
self.user_sp = PythonScriptProvider(self.ctx, u"user")
if self.show_share:
self.share_sp = PythonScriptProvider(self.ctx, u"share")
if self.doc:
self.document_sp = PythonScriptProvider(self.ctx, self.doc)
dialog = OrganizerDialog(
self.ctx,
self.user_sp, self.share_sp, self.document_sp,
self._get_active_frame().getContainerWindow(),
self.show_icon)
result = dialog.execute(self.__class__.History)
if result:
self._store_history(result)
self.run(result)
def _get_provider(self, uri):
""" Find specific provider. """
for p in uri.split("&"):
if p.startswith("location="):
try:
return getattr(self, p[9:] + "_sp")
except:
pass
def run(self, uri):
""" Run script specified by script uri. """
try:
sp = self._get_provider(uri)
if sp:
s = sp.getScript(uri)
if s:
s.invoke((), (), ())
else:
raise ErrorAsMessage("No script found for: \n" + uri)
else:
raise ErrorAsMessage("No provider found for: \n" + uri)
except UNOException, e:
ErrorMessageDialog(
self.ctx, title="Error", message=str(e)).execute()
except ErrorAsMessage, e:
MessageDialog(self.ctx, self._get_active_frame().getContainerWindow(),
type="errorbox", title="Error", message=str(e)).execute()
def user(*args):
""" User's script only. """
ctx = XSCRIPTCONTEXT.getComponentContext()
pso = PythonScriptOrganizer(ctx, True, False, False, True)
pso.execute()
def doc(*args):
""" Both user's and Document's scripts are shown. """
ctx = XSCRIPTCONTEXT.getComponentContext()
pso = PythonScriptOrganizer(ctx, True, False, True, True)
pso.execute()
g_exportedScripts = user, doc
Supported functions:
- Create new script file or directory
- Substitute script file embedded in a document
- Delete script file and directory
- Rename script file and directory
Any Python macros installed by extensions are not shown now.
Edit: Fix according to karolus's post. |