From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- .../source/text/sbasic/python/main0000.xhp | 45 +++ .../source/text/sbasic/python/python_2_basic.xhp | 151 ++++++++++ .../source/text/sbasic/python/python_dialogs.xhp | 75 +++++ .../text/sbasic/python/python_document_events.xhp | 293 +++++++++++++++++++ .../source/text/sbasic/python/python_examples.xhp | 42 +++ .../source/text/sbasic/python/python_handler.xhp | 169 +++++++++++ .../source/text/sbasic/python/python_ide.xhp | 36 +++ .../source/text/sbasic/python/python_import.xhp | 118 ++++++++ .../source/text/sbasic/python/python_listener.xhp | 166 +++++++++++ .../source/text/sbasic/python/python_locations.xhp | 72 +++++ .../source/text/sbasic/python/python_platform.xhp | 129 +++++++++ .../text/sbasic/python/python_programming.xhp | 321 +++++++++++++++++++++ .../source/text/sbasic/python/python_screen.xhp | 108 +++++++ .../source/text/sbasic/python/python_session.xhp | 158 ++++++++++ .../source/text/sbasic/python/python_shell.xhp | 81 ++++++ 15 files changed, 1964 insertions(+) create mode 100644 helpcontent2/source/text/sbasic/python/main0000.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_2_basic.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_dialogs.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_document_events.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_examples.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_handler.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_ide.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_import.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_listener.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_locations.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_platform.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_programming.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_screen.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_session.xhp create mode 100644 helpcontent2/source/text/sbasic/python/python_shell.xhp (limited to 'helpcontent2/source/text/sbasic/python') diff --git a/helpcontent2/source/text/sbasic/python/main0000.xhp b/helpcontent2/source/text/sbasic/python/main0000.xhp new file mode 100644 index 000000000..e84d9b2d3 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/main0000.xhp @@ -0,0 +1,45 @@ + + + + + + Python Scripts + /text/sbasic/python/main0000.xhp + + + + + macros;Python scripts + Python;macros + scripts;Python + +

%PRODUCTNAME Python Scripts Help

+ +
+ %PRODUCTNAME provides an Application Programming Interface (API) that allows controlling the $[officename] components with different programming languages by using the $[officename] Software Development Kit (SDK). For more information about the $[officename] API and the Software Development Kit, visit https://api.libreoffice.org + This help section explains the most common Python script functions for %PRODUCTNAME. For more in-depth information please refer to the Designing & Developing Python Applications on the Wiki. +
+

Working with Python Scripts in %PRODUCTNAME

+ You can execute Python scripts choosing Tools - Macros - Run Macro. Editing scripts can be done with your preferred text editor. Python scripts are present in various locations detailed hereafter. You can refer to Programming examples for macros illustrating how to run the Python interactive console from %PRODUCTNAME. + + + The %PRODUCTNAME scripting framework for Python is optional on some GNU/Linux distributions. If it is installed, selecting Tools - Macros - Run Macro and checking Application Macros for the presence of HelloWorld – HelloWorldPython macro is sufficient. If absent, please refer to your distribution documentation in order to install the %PRODUCTNAME scripting framework for Python. + + + + + + + + + + + +
diff --git a/helpcontent2/source/text/sbasic/python/python_2_basic.xhp b/helpcontent2/source/text/sbasic/python/python_2_basic.xhp new file mode 100644 index 000000000..0ce9f4417 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_2_basic.xhp @@ -0,0 +1,151 @@ + + + + + + Python to Basic + /text/sbasic/python/python_2_basic.xhp + + + + + Python;Calling Basic + ParamArray + +

Calling Basic Macros from Python

+ You can call %PRODUCTNAME Basic macros from Python scripts, and notable features can be obtained in return such as: + + Simple logging facilities out of Access2Base library Trace console, + InputBox and MsgBox screen I/O functions based on Basic to ease Python development, + Xray calls interrupting Python script execution to help inspect variables. + +
+ The %PRODUCTNAME Application Programming Interface (API) Scripting Framework supports inter-language script execution between Python and Basic, or other supported programming languages for that matter. Arguments can be passed back and forth across calls, provided that they represent primitive data types that both languages recognize, and assuming that the Scripting Framework converts them appropriately. +
+ It is recommended to have knowledge of Python standard modules and %PRODUCTNAME API features prior to perform inter-language calls from Python to Basic, JavaScript or any other script engine. + + When running Python scripts from an Integrated Development Environment (IDE), the %PRODUCTNAME-embedded Basic engine may be absent. Avoid Python-to-%PRODUCTNAME Basic calls in such contexts. However Python environment and Universal Networks Objects (UNO) are fully available. Refer to Setting Up an Integrated IDE for Python for more information. +

Retrieving %PRODUCTNAME Basic Scripts

+ %PRODUCTNAME Basic macros can be personal, shared, or embedded in documents. In order to execute them, Python run time needs to be provided with Basic macro locations. Implementing the com.sun.star.script.provider.XScriptProvider interface allows the retrieval of executable scripts: +
+ + API;script.provider.MasterScriptProviderFactory: Retrieving Basic scripts + API;script.provider.XScript: Executing Basic scripts + API;XScriptProvider: Retrieving Basic scripts + + + import uno + from com.sun.star.script.provider import Xscript + + def getBasicScript(macro='Main', module='Module1', library='Standard', + isEmbedded=False) -> XScript: + '''Grab Basic script object before invocation.''' + ctx = uno.getComponentContext() + smgr = ctx.ServiceManager + if isEmbedded: + desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', ctx) + scriptPro = desktop.CurrentComponent.getScriptProvider() + location = "document" + else: + mspf = smgr.createInstanceWithContext( + "com.sun.star.script.provider.MasterScriptProviderFactory", ctx) + scriptPro = mspf.createScriptProvider("") + location = "application" + scriptName = "vnd.sun.star.script:"+library+"."+module+"."+macro+ \ + "?language=Basic&location="+location + xScript = scriptPro.getScript(scriptName) + return xScript + +
+

Executing %PRODUCTNAME Basic Scripts

+
+ + API;script.provider.XScript : Executing Basic scripts + + The %PRODUCTNAME Software Development Kit (SDK) documentation for com.sun.star.script.provider.XScript interface details the calling convention for inter-language calls. Invocation of functions requires three arrays: + + the first lists the arguments of the called routine + the second identifies modified arguments + the third stores the return values + +
+

Python Syntax

+ results = script.invoke((prompt,buttons,title), (), ()) + script.invoke((message,), tuple, ()) + script.invoke((args), (), results) +

Examples of Personal or Shared Scripts

+ Examples in Input/Output to Screen detail Python to Basic invocation calls. Monitoring Document Events illustrates the usage of *args Python idiom to print a variable number of parameters to Access2Base logging console dialog. + At time of development you can interrupt Python script execution using Xray extension in order to inspect properties and methods of UNO objects. The APSO extension debugger allows object introspection using either Xray either MRI extensions. + + def xray(myObject): + script = getBasicScript(library="XrayTool", module="_Main", macro="Xray") + script.invoke((myObject,), (), ()) + +

Examples of Embedded Scripts in Documents

+ *argsPython simplified syntax can be used in conjunction with %PRODUCTNAME Basic routines that accept a variable number of arguments. Below Print and SUM Python functions call their Basic Print and SUM counterparts, using aforementioned getBasicScript function. Exception handling is not detailed. + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + def Print(*args): + """Outputs the specified strings or numeric expressions in a dialog box.""" + xScript = getBasicScript("Print", "Scripting", embedded=True) + xScript.invoke((args), (), ()) + + def SUM(*args): + """SUM the specified number expression.""" + xScript = getBasicScript("SUM", "Scripting", embedded=True) + res = xScript.invoke((args), (), ()) + return res[0] + + # def getBasicScript() # see above + + def playWithArgs(): + Print("Fun with *args ", -9.81, 297864.681974, 8762E-137) + Print(SUM(45, -9.81, 297864.681974)) + Print(SUM(45, -9.81, 297864.681974, 8762E+137)) + + g_exportedScripts = (playWithArgs,) + + The %PRODUCTNAME Basic Print and SUM document-based routines accept a variable number of arguments. The Private or Public attributes have no effect. The arguments type checking is skipped for clarity. + + Option Compatible ' "Standard.Scripting" module + Option Explicit + + Private Sub Print(ParamArray args() As Variant, Optional sep As String = " ") + ''' Print item list of variable number ''' + ' all CStr() convertible args are accepted + Dim str As String, i As Integer + If UBound(args) >= 0 Then + For i = 0 To UBound(args) + str = str + Cstr(args(i))+ sep + Next i + End If + Print str + End Sub ' Standard.Scripting.Print() + + Public Function SUM(ParamArray args() As Variant) As Variant + ''' SUM a variable list of numbers ''' + Dim ndx As Integer + If UBound(args) >= 0 Then + For ndx = 0 To UBound(args) + SUM = SUM + args(ndx) + Next ndx + End If + End Function ' Standard.Scripting.SUM() + +
+ + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_dialogs.xhp b/helpcontent2/source/text/sbasic/python/python_dialogs.xhp new file mode 100644 index 000000000..ee6c6ee0f --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_dialogs.xhp @@ -0,0 +1,75 @@ + + + + + + Opening a Dialog with Python + /text/sbasic/python/python_dialogs.xhp + + + + + Python;dialogs + dialog box;Python + dialogs;Python + +
+

Opening a Dialog with Python

+
+ %PRODUCTNAME static dialogs are created with the Dialog editor and are stored in varying places according to their personal (My Macros), shared (Application Macros) or document-embedded nature. In reverse, dynamic dialogs are constructed at runtime, from Basic or Python scripts, or using any other %PRODUCTNAME supported language for that matter. Opening static dialogs with Python is illustrated herewith. Exception handling and internationalization are omitted for clarity. +

My Macros or Application Macros dialogs

+ The examples below open Access2Base Trace console or the imported TutorialsDialog dialog with Tools - Macros - Run Macro menu: + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + def consoleDlg(): + ctx =XSCRIPTCONTEXT.getComponentContext() + smgr = ctx.getServiceManager() + dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx) + dlg = dp.createDialog( "vnd.sun.star.script:Access2Base.dlgTrace?location=application") + dlg.execute() + dlg.dispose() + + def tutorDialog(): + ctx =XSCRIPTCONTEXT.getComponentContext() + smgr = ctx.getServiceManager() + dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx) + dlg = dp.createDialog("vnd.sun.star.script:Standard.TutorialsDialog?location=application") + dlg.execute() + dlg.dispose() + + g_exportedScripts = (consoleDlg, tutorDialog) + +

Document embedded dialogs

+ The example below opens a newly edited Dialog1 dialog from a document with Tools - Macros - Run Macro menu: + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + def docDialog(): + """ Display a doc-based dialog """ + model = XSCRIPTCONTEXT.getDocument() + smgr = XSCRIPTCONTEXT.getComponentContext().ServiceManager + dp = smgr.createInstanceWithArguments( "com.sun.star.awt.DialogProvider", (model,)) + dlg = dp.createDialog( "vnd.sun.star.script:Standard.Dialog1?location=document") + dlg.execute() + dlg.dispose() + + g_exportedScripts = (docDialog,) + + Refer to msgbox.py in {installation}/program/ directory for Python dynamic dialog examples. +
+ + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_document_events.xhp b/helpcontent2/source/text/sbasic/python/python_document_events.xhp new file mode 100644 index 000000000..814047b1b --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_document_events.xhp @@ -0,0 +1,293 @@ + + + + + + Monitoring Document Events + /text/sbasic/python/python_document_events.xhp + + + + + Basic;Monitoring Document Events + Python;Monitoring Document Events + Access2Base;Console + Access2Base;Trace + API;document.DocumentEvent: Monitoring Document Event + API;document.XDocumentEventBroadcaster: Monitoring Document Event + API;document.XDocumentEventListener: Monitoring Document Event + API;lang.EventObject: Monitoring Document Event + +
+

Listening to Document Events

+ Listening to document events can help in the following situations: + + + Identify a new document at opening time, as opposed to existing ones, and perform a dedicated setup. + + + Control the processing of document save, document copy, print or mailmerge requests. + + + Recalculate table of contents, indexes or table entries of a Writer document when document is going to be closed + + + Import math Python packages before opening a Calc document. Release these packages when the document closes. + + + Next to assigning macros to events, one can monitor events raised by %PRODUCTNAME documents. Application Programming Interface (API) broadcasters are responsible for calling event scripts. Unlike listeners that require to define all supported methods, even if unused, document monitors require only two methods next to hooked event scripts. +
+

Monitoring Document Events

+ Monitoring is illustrated herewith for Basic and Python languages using object-oriented programming. Assigning OnLoad script, to the Open Document event, suffices to initiate and terminate document event monitoring. Tools - Customize menu Events tab is used to assign either scripts. + Intercepting events helps setting scripts pre- and post-conditions such as loading and unloading libraries or track script processing in the background. Access2Base.Trace module usage is illustrating that second context. +

With Python

+ + API;frame.Desktop: Monitoring Document Event + API;script.provider.MasterScriptProviderFactory: Monitoring Document Event + API;script.provider.XScript: Monitoring Document Event + + Events monitoring starts from object instantiation and ultimately stops when Python releases the object. Raised events are reported using Access2Base console. + OnLoad and OnUnload events can be used to respectively set and unset Python programs path. They are described as Open document and Document closed. + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import os.path, uno, unohelper + from com.sun.star.document import DocumentEvent, \ + XDocumentEventListener as AdapterPattern + from com.sun.star.lang import EventObject + + class UiDocument(unohelper.Base, AdapterPattern): + """ Monitor document events """ + ''' + adapted from 'Python script to monitor OnSave event' at + https://forum.openoffice.org/en/forum/viewtopic.php?t=68887 + ''' + def __init__(self): + """ Document events monitor """ + ''' report using Access2Base.Trace console OR + report in 1st sheet, 1st column for Calc docs ''' + ctx = uno.getComponentContext() + smgr = ctx.getServiceManager() + desktop = smgr.createInstanceWithContext( + 'com.sun.star.frame.Desktop' , ctx) + self.doc = desktop.CurrentComponent + #self.row = 0 # uncomment for Calc documents only + Console.setLevel("DEBUG") + self.listen() # Start monitoring doc. events + + @property + def Filename(self) -> str: + sys_filename = uno.fileUrlToSystemPath(self.doc.URL) + return os.path.basename(sys_filename) + + def setCell(self, calcDoc, txt: str): + """ Output doc. events on 1st column of a Calc spreadsheet """ + sheet = calcDoc.getSheets().getByIndex(0) + sheet.getCellByPosition(0,self.row).setString(txt) + self.row = self.row + 1 + + def listen(self, *args): # OnLoad/OnNew at the earliest + """ Start doc. events monitoring """ + self.doc.addDocumentEventListener(self) + Console.log("INFO", "Document events are being logged", True) + + def sleep(self, *args): # OnUnload at the latest (optional) + """ Stop doc. events monitoring """ + self.doc.removeDocumentEventListener(self) + Console.log("INFO", "Document events have been logged", True) + + def documentEventOccured(self, event: DocumentEvent): + """ Intercepts all doc. events """ + #self.setCell(event.Source, event.EventName) # only for Calc docs + Console.log("DEBUG", + event.EventName+" in "+self.Filename, + False) + + def disposing(self, event: EventObject): + """ Release all activities """ + self.sleep() + Console.show() + + def OnLoad(*args): # 'Open Document' event + listener = UiDocument() # Initiates listening + + def OnUnload(*args): # 'Document has been closed' event + pass # (optional) performed when disposed + + g_exportedScripts = (OnLoad,) + + from com.sun.star.script.provider import XScript + class Console(): + """ + (Back/Fore)ground console to report/log program execution. + """ + @staticmethod + def trace(*args,**kwargs): + """ Print free item list to console """ + scr = Console._a2bScript(script='DebugPrint', module='Compatible') + scr.invoke((args),(),()) + @staticmethod + def log(level: str, text: str, msgBox=False): + """ Append log message to console, optional user prompt """ + scr = Console._a2bScript(script='TraceLog') + scr.invoke((level,text,msgBox),(),()) + @staticmethod + def setLevel(logLevel: str): + """ Set log messages lower limit """ + scr = Console._a2bScript(script='TraceLevel') + scr.invoke((logLevel,),(),()) + @staticmethod + def show(): + """ Display console content/dialog """ + scr = Console._a2bScript(script='TraceConsole') + scr.invoke((),(),()) + @staticmethod + def _a2bScript(script: str, library='Access2Base', + module='Trace') -> XScript: + ''' Grab application-based Basic script ''' + sm = uno.getComponentContext().ServiceManager + mspf = sm.createInstanceWithContext( + "com.sun.star.script.provider.MasterScriptProviderFactory", + uno.getComponentContext()) + scriptPro = mspf.createScriptProvider("") + scriptName = "vnd.sun.star.script:"+library+"."+module+"."+script+"?language=Basic&location=application" + xScript = scriptPro.getScript(scriptName) + return xScript + + Mind the misspelled documentEventOccured method that inherits a typo from %PRODUCTNAME Application Programming Interface (API). + Start application and Close application events can respectively be used to set and to unset Python path for user scripts or %PRODUCTNAME scripts. In a similar fashion, document based Python libraries or modules can be loaded and released using Open document and Document closed events. Refer to Importing Python Modules for more information. +

With %PRODUCTNAME Basic

+ + API;GlobalScope.BasicLibraries + Tools;Strings + + Using Tools - Customize menu Events tab, the Open document event fires a ConsoleLogger initialisation. _documentEventOccured routine - set by ConsoleLogger - serves as a unique entry point to trap all document events. +

controller.Events module

+ + Option Explicit + + Global _obj As Object ' controller.ConsoleLogger instance + + Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Open Document << + _obj = New ConsoleLogger : _obj.StartAdapter(evt) + End Sub ' controller.OnLoad + Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent) + ''' ConsoleLogger unique entry point ''' + _obj.DocumentEventOccurs(evt) + End Sub ' controller._documentEventOccured + +

controller.ConsoleLogger class module

+ Events monitoring starts from the moment a ConsoleLogger object is instantiated and ultimately stops upon document closure. StartAdapter routine loads necessary Basic libraries, while caught events are reported using Access2Base.Trace module. + + Option Explicit + Option Compatible + Option ClassModule + + ' ADAPTER design pattern object to be instantiated in the "Open Document" event + Private Const UI_PROMPT = True + Private Const UI_NOPROMPT = False ' Set it to True to visualise documents events + + ' MEMBERS + Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster + Private _txtMsg As String ' text message to log in console + + ' PROPERTIES + Private Property Get FileName As String + ''' System-dependent filename ''' + Const _LIBRARY = "Tools" : With GlobalScope.BasicLibraries + If Not .IsLibraryLoaded(_LIBRARY) Then .LoadLibrary(_LIBRARY) + End With + Filename = Tools.Strings.FilenameOutofPath(ThisComponent.URL) + End Property ' controller.ConsoleLogger.Filename + + ' METHODS + Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent) + ''' Monitor document events ''' + Access2Base.Trace.TraceLog("DEBUG", _ + evt.EventName &" in "& Filename(evt.Source.URL), _ + UI_NOPROMPT) + Select Case evt.EventName + Case "OnUnload" : _StopAdapter(evt) + End Select + End Sub ' controller.ConsoleLogger.DocumentEventOccurs + + Public Sub StartAdapter(Optional evt As com.sun.star.document.DocumentEvent) + ''' Initialize document events logging ''' + Const _LIBRARY = "Access2Base" : With GlobalScope.BasicLibraries + If Not .IsLibraryLoaded(_LIBRARY) Then .LoadLibrary(_LIBRARY) + End With : Access2Base.Trace.TraceLevel("DEBUG") + If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-" + Access2Base.Trace.TraceLog("INFO", _txtMsg & "Document events are being logged", UI_PROMPT) + _evtAdapter = CreateUnoListener( "_", "com.sun.star.document.XDocumentEventListener" ) + ThisComponent.addDocumentEventListener( _evtAdapter ) + End Sub ' controller.ConsoleLogger.StartAdapter + + Private Sub _StopAdapter(Optional evt As com.sun.star.document.DocumentEvent) + ''' Terminate document events logging ''' + ThisComponent.removeDocumentEventListener( _evtAdapter ) + If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-" + Access2Base.Trace.TraceLog("INFO", _txtMsg & "Document events have been logged", UI_PROMPT) + Access2Base.Trace.TraceConsole() ' Captured events dialog + End Sub ' controller.ConsoleLogger._StopAdapter + + ' EVENTS + ' Your code for handled events goes here + + Mind the misspelled _documentEventOccured method that inherits a typo from %PRODUCTNAME Application Programming Interface (API). +

Discovering Documents Events

+ + API;frame.GlobalEventBroadcaster: Monitoring Document Event + + The broadcaster API object provides the list of events it is responsible for: +

With Python

+ + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import uno, apso_utils as ui + + def displayAvailableEvents(): + """ Display document events """ + ''' + adapted from DisplayAvailableEvents() by A. Pitonyak + https://forum.openoffice.org/en/forum/viewtopic.php?&t=43689 + ''' + ctx = XSCRIPTCONTEXT.getComponentContext() + smgr = ctx.ServiceManager + geb = smgr.createInstanceWithContext( + "com.sun.star.frame.GlobalEventBroadcaster", ctx) + events = geb.Events.getElementNames() + ui.msgbox('; '.join(events)) + + g_exportedScripts = (displayAvailableEvents,) + + The Alternative Python Script Organizer (APSO) extension is used to render events information on screen. +

With %PRODUCTNAME Basic

+ + Sub DisplayAvailableEvents + ''' Display document events ''' + Dim geb As Object ' com.sun.star.frame.GlobalEventBroadcaster + Dim events() As String + geb = CreateUnoService("com.sun.star.frame.GlobalEventBroadcaster") + events = geb.Events.ElementNames() + MsgBox Join(events, "; ") + End Sub + +
+ + + + + + +
+ +
\ No newline at end of file diff --git a/helpcontent2/source/text/sbasic/python/python_examples.xhp b/helpcontent2/source/text/sbasic/python/python_examples.xhp new file mode 100644 index 000000000..c5b496ed0 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_examples.xhp @@ -0,0 +1,42 @@ + + + + + + Python examples + /text/sbasic/python/python_examples.xhp + + + +
+ + Python;examples + Python;shell + Python;platform + Python;session + Python;screen input/output + +

Python programming examples

+
+ + + + + + + + + +
+ + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_handler.xhp b/helpcontent2/source/text/sbasic/python/python_handler.xhp new file mode 100644 index 000000000..87887105e --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_handler.xhp @@ -0,0 +1,169 @@ + + + + + + Creating A Dialog Handler + /text/sbasic/python/python_handler.xhp + + + + + Basic;Dialog Handler + Python;Dialog Handler + Access2Base;dlgTrace + Access2Base;_DumpToFile + API;DialogProvider2 + API;XDialogEventHandler + + +

Creating a Dialog Handler

+ Next to assigning macros to events or creating event listeners, one can use dialog handlers, whose principle is to define UNO keywords, or methods, that are mapped to events to watch for. The event handler is responsible for executing methods using the vnd.sun.star.UNO:<method_name> protocol. Unlike listeners that require to define all supported methods, even if unused, dialog handlers require only two methods on top of intended control hook scripts. + The advantages of this approach are: + + It packs the code that handles event-driven macros, + it decorrelates events from macros names which facilitates maintenance or updates, in particular when moving macros or modules. + + This mechanism is illustrated herewith for Basic and Python languages using an imported copy of Access2Base dlgTrace dialog. Exception handling and localisation are omitted for clarity. +

Assigning Dialog methods

+ Export Access2Base dlgTrace dialog and import it into MyLib application library. + Inside the control properties pane of the Dialog Editor, use the Events tab to replace macro assignments by component assignments, and type in the intended method names: + + Set Dump to file dialog button component method name to _dump2File + Optionally define txtTracelog key pressed and mouse button pressed events component method names as _openHelp + Optionally define Ok button receiving focus event component method name as onOkHasfocus + + Events assigned actions should mention the vnd.sun.star.UNO: protocol. +

Creating the handler

+ createDialogWithHandler method of com.sun.star.awt.DialogProvider2 service is used to set the dialog and its handler. The handler is responsible for implementing com.sun.star.awt.XDialogEventHandler interface. + All component method names must be explicitly declared when using a dialog handler. +

With Python

+ In this example the dialog is located on the computer. + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import uno, unohelper + from com.sun.star.awt import XDialogEventHandler + + _DLG_PROVIDER = "com.sun.star.awt.DialogProvider2" + + class Console(unohelper.Base, XDialogEventHandler): + """ Access2Base Console Handler """ + ''' adapted from « Créer un dialogue avec gestionnaire d'événements » by JM Zambon + https://wiki.openoffice.org/wiki/FR/Documentation/Python/Creating_Dialog_with_Handler ''' + def show(self): + dialog = self.getDialog("MyLib.dlgTrace", embedded=True) + dialog.Title = "Konsole" + dialog.execute() + + def callHandlerMethod(self, dialog, event, method): + if method == '_dump2File': + event.Source.setLabel("dump requested") + scr = getBasicScript(script="_DumpToFile", module="Trace", + library='Access2Base') + scr.invoke((event,), (), ()) + elif method == '_openHelp': + _msgbox('Not yet implemented') + dialog.endDialog(1) + else: + return False + + def getSupportedMethodNames(self): + return ('_dump2File', '_openHelp') + + def getDialog(self, libr_dlg: str, embedded=False): + """ Create a Dialog from its location """ + smgr = XSCRIPTCONTEXT.getComponentContext().ServiceManager + if embedded: + model = XSCRIPTCONTEXT.getDocument() + dp = smgr.createInstanceWithArguments(_DLG_PROVIDER, (model,)) + location = "?location=document" + else: + dp = smgr.createInstanceWithContext(_DLG_PROVIDER, ctx) + location = "?location=application" + dlg = dp.createDialogWithHandler("vnd.sun.star.script:"+libr_dlg+location, self) + return dlg + + + # def getBasicScript() # see note + + def _msgbox(prompt='', title=''): + ''' Ugly MsgBox ''' + import msgbox + mb = msgbox.MsgBox(uno.getComponentContext()) + mb.addButton('Howdy') + mb.show(prompt,0,title) + + def ConsoleHandler(): + Console().show() + + g_exportedScripts = (ConsoleHandler,) + + + As expected, onOkHasFocus missing method throws an exception. + Refer to Python calls to %PRODUCTNAME Basic page for getBasicScript routine description and for details about cross-language scripting execution. +

With %PRODUCTNAME Basic

+ In this example the dialog is embedded in a document, and can equally be located on the computer. + + ' <MyLib>.<Handler> module + + Public Sub Console_Show() + Dim dp as Object ' com.sun.star.awt.DialogProvider2 + Dim dialog As Object ' com.sun.star.awt.XDialog, com.sun.star.awt.XDialogEventHandler + Dim eventHandler As Object ' com.sun.star.awt.XDialogEventHandler + dp = CreateUnoService("com.sun.star.awt.DialogProvider2") + dp.Initialize(Array(ThisComponent)) ' if doc-embedded dialog + eventHandler = CreateUnoListener("Console_", "com.sun.star.awt.XDialogEventHandler") + dialog = dp.createDialogWithHandler("vnd.sun.star.script:MyLib.dlgTrace?location=document", eventHandler) + dialog.Title = "Konsole" + dialog.execute() + End Sub ' <Handler>.Console_Show() + + Private Function Console_callHandlerMethod(dialog as Object, _ + event As com.sun.star.document.DocumentEvent, _ + method As String) As Boolean + ''' Intercept dialog events using .UNO protocol ''' + Console_callHandlerMethod = True + Select Case method + Case "_dump2File" + event.Source.setLabel("dump requested") + With GlobalScope.BasicLibraries + If Not .IsLibraryLoaded("Access2Base") Then .LoadLibrary("Access2Base") + End With + Access2Base.Trace._DumpToFile + Case "_openHelp" + MsgBox "Not yet implemented",0 , "Howdy" + 'dialog.endDialog(1) if computer-based dialog + Case Else : Console_callHandlerMethod = False + End Select + End Function ' <Handler>.Console_callHandlerMethod + + Private Function Console_getSupportedMethodNames() + Console_getSupportedMethodNames = Array("_dump2File", "_openHelp") + End Function ' <Handler>.Console _getSupportedMethodNames + + ' adapted from « Créer un dialogue avec gestionnaire d'événements » by JM Zambon + ' https://wiki.openoffice.org/wiki/FR/Documentation/Python/Creating_Dialog_with_Handler + + As expected, onOkHasFocus missing method throws an exception. +
+ + + CreateUnoListener Function + + + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_ide.xhp b/helpcontent2/source/text/sbasic/python/python_ide.xhp new file mode 100644 index 000000000..e6d715630 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_ide.xhp @@ -0,0 +1,36 @@ + + + + + + IDE for Python + /text/sbasic/python/python_ide.xhp + + + +
+ + + APSO + Alternative Python Scripts Organizer + python;IDE - integrated development environment + python;editor + +

Setting up an Integrated Development Environment (IDE) for Python

+ Writing Python macros requires extra configuration steps to set an IDE of choice. +
+ Unlike Basic language macros development in %PRODUCTNAME, developing Python scripts for %PRODUCTNAME requires to configure an external Integrated Development Environment (IDE). Multiple IDEs are available that range from beginners to advanced Python coders. While using a Python IDE programmers benefit from numerous features such as syntax highlighting, code folding, class browsing, code completion, coding standard enforcement, test driven development, debugging, version control and many more. You can refer to Designing & Developing Python Applications on the Wiki for more in-depth information about the setup of a bridge between your IDE and a running instance %PRODUCTNAME. +

The APSO Extension

+ The Alternative Python Script Organizer (APSO) extension eases the edition of Python scripts, in particular when embedded in a document. Using APSO you can configure your preferred source code editor, start the integrated Python shell and debug Python scripts. Extensions exist that help inspect arbitrary UNO objects, refer to Designing & Developing Python Applications for additional details on such extensions. +
+ +
+ +
\ No newline at end of file diff --git a/helpcontent2/source/text/sbasic/python/python_import.xhp b/helpcontent2/source/text/sbasic/python/python_import.xhp new file mode 100644 index 000000000..af3b243d3 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_import.xhp @@ -0,0 +1,118 @@ + + + + + + Python : Importing Modules + /text/sbasic/python/python_import.xhp + + + + + Python;import + Python;Modules + Python;pythonpath + PythonLibraries + +

Importing Python Modules

+ %PRODUCTNAME Python scripts come in three distinct flavors, they can be personal, shared or embedded in documents. They are stored in varying places described in Python Scripts Organization and Location. In order to import Python modules, their locations must be known from Python at run time. + This mechanism is illustrated for file system based modules and document based modules. Exception handling is omitted for clarity. The terms library or directory, scripts or modules are used interchangeably. A Python macro refers to a function inside a module. + Note that <User Profile>/Scripts/python/pythonpath local directory is always explored when running a Python macro from <User Profile>/Scripts/python. +

File System module import

+ +

User or Shared Modules

+ Personal & shared Python scripts can be imported once their directories are included in Python run time path. Refer to Getting session information page for more details regarding omitted Session Class. + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + import sys + + user_lib = Session().UserPythonScripts # User scripts location + if not user_lib in sys.path: + sys.path.insert(0, user_lib) # Add to search path + import screen_io as ui # 'screen_io.py' module resides in user_lib directory + # Your code follows here + + This Python example exposes a local XSCRIPTCONTEXT variable to an imported module: + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + import uno, sys + + share_lib = Session.SharedPythonScripts() # Shared scripts location + if not share_lib in sys.path: + sys.path.insert(0, share_lib) # Add to search path + from IDE_utils import ScriptContext # 'IDE_utils.py' sits with shared Python scripts. + XSCRIPTCONTEXT = ScriptContext(uno.getComponentContext) + # Your code follows here + +

Installation Modules for Applications

+ Unlike personal and shared scripts, %PRODUCTNAME installation scripts can be imported any time. Next to uno & unohelper %PRODUCTNAME Python modules, other scripts present in <installation_path>/program directory can be imported directly, such as the msgbox module. + With Python shell: + >>> import msgbox, uno + >>> myBox = msgbox.MsgBox(uno.getComponentContext()) + >>> myBox.addButton("okay") + >>> myBox.renderFromButtonSize() + >>> myBox.numberOflines = 2 + >>> print(myBox.show("A small message",0,"Dialog title")) +

Document Module Import

+ Importing a Python document embedded module is illustrated below. Error handling is not detailed. Python run time path is updated when document has been opened and before closure. Refer to Event-Driven Macros to learn how to associate Python macros to document events. + + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import sys, uno + + def OnDocPostOpenLoadPython(): + """ Prepare Python modules import when doc. loaded """ + PythonLibraries.loadLibrary('lib/subdir') # Add directory to search path + PythonLibraries.loadLibrary('my_gui', 'screen_io') # Add dir. & import screen_io + + def OnDocQueryCloseUnloadPython(): + """ Cleanup PYTHON_PATH when doc. Gets closed """ + PythonLibraries.unloadLibrary('my_gui') # Python runtime path cleanup + # Note: imported modules remain loaded in this example. + + class PythonLibraries(): + """ Python library loader and module importer + + adapted from 'Bibliothèque de fonctions' by Hubert Lambert + at https://forum.openoffice.org/fr/forum/viewtopic.php?p=286213 """ + def isImportedModule(module_name: str) -> bool: + """ Check run time module list """ + return (module_name in sys.modules.keys()) + def isLoadedLibrary(lib_name: str) -> bool: + """ Check PYTHON_PATH content """ + return (lib_name in sys.path) + def loadLibrary(lib_name: str, module_name=None): + """ add directory to PYTHON_PATH, import named module """ + doc = XSCRIPTCONTEXT.getDocument() + url = uno.fileUrlToSystemPath( + '{}/{}'.format(doc.URL,'Scripts/python/'+lib_name) + if not url in sys.path: + sys.path.insert(0, url) + if module_name and not module_name in sys.modules.keys(): + return zipimport.zipimporter(url).load_module(module_name) + def unloadLibrary(lib_name: str): + """ remove directory from PYTHON_PATH """ + sys.path.remove(lib_name) + + g_exportedScripts = (OnDocPostOpenLoadPython, OnDocQueryCloseUnloadPython) + +
+ + + + + Refer to Creating a Python Listener for examples of event-driven macros. + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_listener.xhp b/helpcontent2/source/text/sbasic/python/python_listener.xhp new file mode 100644 index 000000000..6cffde6a6 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_listener.xhp @@ -0,0 +1,166 @@ + + + + + + Python Listeners : Creating Event Listeners + /text/sbasic/python/python_listener.xhp + + + + + Python;Event Listener + Python;createUnoListener + Basic;Event Listener + API;ActionEvent + API;DialogProvider + API;EventObject + API;ExecutableDialogResults + API;XActionListener + +
+

Creating Event Listeners

+
+ Events raised by dialogs, documents, forms or graphical controls can be linked to macros, which is referred to as event-driven programming. The most common method to relate events to macros are the Events tab in Tools – Customize menu and the Dialog Editor Control properties pane from Tools - Macros – Organise Dialogs... menu. + Graphical artifacts, keyboard inputs, mouse moves and other man/machine interactions can be controlled using UNO listeners that watch for the user’s behavior. Listeners are dynamic program code alternatives to macro assignments. One may create as many UNO listeners as events to watch for. A single listener can also handle multiple user interface controls. +

Creating an event listener

+ Listeners get attached to controls held in dialogs, as well as to document or form events. Listeners are also used when creating runtime dialogs or when adding controls to a dialog on the fly. + This example creates a listener for Button1 control of Dialog1 dialog in Standard library. +

With Python

+ + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import uno, unohelper + from com.sun.star.awt import XActionListener + from com.sun.star.awt import ActionEvent + from com.sun.star.lang import EventObject + from com.sun.star.ui.dialogs.ExecutableDialogResults \ + import OK, CANCEL + import msgbox as util + + _MY_BUTTON = "Button1" + _MY_LABEL = 'Python listens..' + _DLG_PROVIDER = "com.sun.star.awt.DialogProvider" + + def Main(*args): + ui = createUnoDialog("Standard.Dialog1", embedded=True) + ui.Title = "Python X[any]Listener" + ctl = ui.getControl(_MY_BUTTON) + ctl.Model.Label = _MY_LABEL + act = ActionListener() + ctl.addActionListener(act) + rc = ui.execute() + if rc == OK: + MsgBox("The user acknowledged the dialog.") + elif rc == CANCEL: + MsgBox("The user canceled the dialog.") + ui.dispose() # ui.endExecute + ctl.removeActionListener(act) + + def createUnoDialog(libr_dlg: str, embedded=False): + """ Create a Dialog from its location """ + smgr = XSCRIPTCONTEXT.getComponentContext().ServiceManager + if embedded: + model = XSCRIPTCONTEXT.getDocument() + dp = smgr.createInstanceWithArguments(_DLG_PROVIDER, (model,)) + location = "?location=document" + else: + dp = smgr.createInstanceWithContext(_DLG_PROVIDER, ctx) + location = "?location=application" + dlg = dp.createDialog("vnd.sun.star.script:"+libr_dlg+location) + return dlg + + class ActionListener(unohelper.Base, XActionListener): + """ Listen to & count button clicks """ + def __init__(self): + self.count = 0 + + def actionPerformed(self, evt: ActionEvent): + self.count = self.count + 1 + #mri(evt) + if evt.Source.Model.Name == _MY_BUTTON: + evt.Source.Model.Label = _MY_LABEL+ str( self.count ) + return + + def disposing(self, evt: EventObject): # mandatory routine + pass + + def MsgBox(txt: str): + mb = util.MsgBox(uno.getComponentContext()) + mb.addButton("Ok") + mb.show(txt, 0, "Python") + + g_exportedScripts = (Main,) + + + msgbox.py in {installation}/program/ directory has some examples of button listeners. + +

With %PRODUCTNAME Basic

+ + Option Explicit + + Const MY_LIBRARY = "Standard", MY_DIALOG = "Dialog1", MY_BUTTON = "Button1" + Const MY_LABEL = "Basic listens.." + Dim count As Integer + + Sub Main + Dim libr As Object ' com.sun.star.script.XLibraryContainer + Dim dlg As Object + Dim ui As Object ' stardiv.Toolkit.UnoDialogControl + Dim ctl As Object ' stardiv.Toolkit.UnoButtonControl + Dim act As Object ' com.sun.star.awt.XActionListener + Dim rc As Object : rc = com.sun.star.ui.dialogs.ExecutableDialogResults + + BasicLibraries.LoadLibrary(MY_LIBRARY) + libr = DialogLibraries.GetByName(MY_LIBRARY) + dlg = libr.GetByName(MY_DIALOG) + ui = CreateUnoDialog(dlg) + ui.Title = "Basic X[any]Listener example" + count = 0 + ctl = ui.GetControl(MY_BUTTON) + ctl.Model.Label = MY_LABEL + act = CreateUnoListener("awt_", "com.sun.star.awt.XActionListener") + ctl.addActionListener(act) + Select Case ui.Execute + Case rc.OK : MsgBox "The user acknowledged the dialog.",, "Basic" + Case rc.CANCEL : MsgBox "The user canceled the dialog.",, "Basic" + End Select + ui.dispose ' ui.endExecute() + ctl.removeActionListener(act) + End Sub + + Private Sub awt_actionPerformed(evt As com.sun.star.awt.ActionEvent) + ''' Listen to & count button clicks ''' + With evt.Source.Model + If .Name = MY_BUTTON Then + count = count + 1 + .Label = MY_LABEL+Cstr(count) + End If + End With + End Sub ' awt_actionPerformed + + Private Sub awt_disposing(evt As com.sun.star.lang.EventObject) ' mandatory Sub + ' your code goes here + End Sub ' awt_disposing + +

Other Event Listeners

+ Listeners are usually coded along with dialog opening. Numerous listener approaches are possible such as event handlers for dialogs or event monitors for documents or forms. +
+ + CreateUnoListener Function + Events mapping to objects + See also Document events, Form events. + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_locations.xhp b/helpcontent2/source/text/sbasic/python/python_locations.xhp new file mode 100644 index 000000000..9f145416a --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_locations.xhp @@ -0,0 +1,72 @@ + + + + + + + Python Scripts Organization + /text/sbasic/python/python_locations.xhp + + + +
+ Python Scripts Organization and Location + %PRODUCTNAME macros are grouped in module files, modules are usually grouped in library folders, and libraries are grouped in library containers although containers can contain modules too. + A library is used as a major grouping for either an entire category of macros, or for an entire application. Modules usually split functionality, such as user interaction and calculations. Individual macros are subroutines and functions. The Figure below shows an example of the hierarchical structure of macro libraries in %PRODUCTNAME. + Library Container diagram + Figure: Macro Library hierarchy + The containers are accessible in all %PRODUCTNAME programs through the user interface. Go to Tools > Macros > Organize Macros > Python, to open the Python Macros dialog. + Three library containers are shown in the Macro From list: + + + My Macros: personal macros available for the %PRODUCTNAME user + + + Application Macros: system macros distributed with %PRODUCTNAME for every computer user + + + Document macros: every document can contain macro libraries available in that document for all users + + +
+

Python Script Locations

+ Refer to Getting Session Information in order to get programmatic access to Python script locations. +

Application Macros

+ Existing macros in this location (container) were copied by the installation program and are available to every computer user, and any open document can access macros stored the container. You need administrative rights to store or edit macros here. + The %PRODUCTNAME Macros container location in the file system depends on the operating system: + + + For Windows: {Installation}\share\Scripts\python. + + + For Linux and macOS: {Installation}/share/Scripts/python. + + +

My Macros

+ This container is accessible only by the %PRODUCTNAME user. Any open document can access macros stored the container. Macros in this location are stored in the %PRODUCTNAME user profile. + The My Macros container location is in the user space and depends on the operating system: + + + For Windows,
%APPDATA%\LibreOffice\4\user\Scripts\python.
+
+ + For Linux and macOS,
$HOME/.config/libreoffice/4/user/Scripts/python.
+
+
+

Document macros

+ Document macros are embedded in the document and are accessible only when the document is open. +

Libraries, Modules and Macros

+ Python macros can be organized in libraries, modules and macros. Use the Macro Library hierarchy as a guide when creating or installing new macros in module files, new module files in library folders or new library folders in containers. +
+ + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_platform.xhp b/helpcontent2/source/text/sbasic/python/python_platform.xhp new file mode 100644 index 000000000..364e067f3 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_platform.xhp @@ -0,0 +1,129 @@ + + + + + + Python : Platform class + /text/sbasic/python/python_platform.xhp + + + + + Platform;isLinux + Platform;isMacOsX + Platform;isWindows + Platform;ComputerName + Platform;OSName + API;ConfigurationAccess + Tools;GetRegistryContent + +

Identifying the operating system

+ Identifying the operating system can be performed with Python or Basic language. + ComputerName property is solely available for Windows. Basic calls to Python macros help overcome %PRODUCTNAME Basic limitations. +

Using a Python class:

+ + import os, platform + class Platform(): + @property + def ComputerName(self): return platform.node() + @property + def DirSeparator(self): return os.sep + @property + def isLinux(self): return (self.OSName=='Linux') + @property + def isMacOSX(self): return (self.OSName=='Darwin') + @property + def isWindows(self): return (self.OSName=='Windows') + @property + def OSName(self): return platform.system() + @property + def PathDelimiter(self): return os.pathsep + +

Using a Basic classmodule:

+ %PRODUCTNAME Basic lacks MacOS X native recognition. Platform identification is possible using %PRODUCTNAME Application Programming Interface (API). + + Option Compatible + Option ClassModule + Option Explicit + + Public Property Get ComputerName As String + If isWindows Then ComputerName = Environ("ComputerName") + End Property ' Platform.ComputerName + + Public Property Get DirSeparator As String + DirSeparator = GetPathSeparator() + End Property ' Platform.DirSeparator + + Public Property Get IsLinux As Boolean + isLinux = ( GetGUIType()=4 ) ' Applies to macOS as well + End Property ' Platform.isLinux + + Public Property Get IsMacOSX As Boolean + isMacOSX = ( OSName="MAC" ) + End Property ' Platform.isMacOSX + + Public Property Get IsWindows As Boolean + isWindows = ( GetGUIType()=1 ) + End Property ' Platform.isWindows + + Public Property Get OSName As String + ' Return platform name as "MAC", "UNIX", "WIN" + ' Inferred from "Tools.UCB.ShowHelperDialog" function + With GlobalScope.Basiclibraries + If Not .IsLibraryLoaded("Tools") Then .LoadLibrary("Tools") + End With + Dim keyNode As Object ' com.sun.star.configuration.ConfigurationAccess + keyNode = Tools.Misc.GetRegistryKeyContent("org.openoffice.Office.Common/Help") + OSName = keyNode.GetByName("System") + End Property ' Platform.OSName + + Public Property Get PathDelimiter As String + Select Case OSName + Case "MAC", "UNIX" : PathDelimiter = ":" + Case "WIN" : PathDelimiter = ";" + End Select + End Property ' Platform.PathDelimiter + +

Examples:

+ With Python + >>> from <the_module> import Platform + >>> print(Platform().isMacOSX) # object property + True + >>> input(Platform().OSName) # object property + Darwin + + From Tools – Macros - Run Macro... menu. + + from <the_module> import Platform + import screen_io as ui + p = Platform() + ui.MsgBox(''.join(['isMacOS: ',str(p.isMacOSX)]),0,p.OSName) + + With %PRODUCTNAME Basic + + Sub Platform_example() + Dim p As New Platform ' instance of Platform class + MsgBox p.isLinux ' object property + Print p.isWindows, p.OSName ' object properties + End Sub ' Platform_example + +
+ + + + + + +
+ +
\ No newline at end of file diff --git a/helpcontent2/source/text/sbasic/python/python_programming.xhp b/helpcontent2/source/text/sbasic/python/python_programming.xhp new file mode 100644 index 000000000..96deb8606 --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_programming.xhp @@ -0,0 +1,321 @@ + + + + + + Python : Programming with Python + /text/sbasic/python/python_programming.xhp + + + + + Python;Programming + XSCRIPTCONTEXT;Python + XSCRIPTCONTEXT;getComponentContext() + uno.py + uno.py;getComponentContext() + +
+

Programming with Python Scripts

+
+ A Python macro is a function within a .py file, identified as a module. Unlike %PRODUCTNAME Basic and its dozen of UNO objects functions or services, Python macros use the XSCRIPTCONTEXT UNO single object, shared with JavaScript and BeanShell. The g_exportedScripts global tuple explicitly lists selectable macros from a module. Python modules hold autonomous code logic, and are independent from one another. +

XSCRIPTCONTEXT Global Variable

+ Genuine Basic UNO facilities can be inferred from XSCRIPTCONTEXT global variable. Refer to %PRODUCTNAME API for a complete description of XSCRIPTCONTEXT. XSCRIPTCONTEXT methods summarize as: + + + + Methods + + + Description + + + Mapped in Basic as + + + + + getDocument() + + + The document reference on which the script can operate. + + + ThisComponent + + + + + getDesktop() + + + The desktop reference on which the script can operate. + + + StarDesktop + + + + + getComponentContext() + + + The component context which the script can use to create other uno components. + + + GetDefaultContext + + +
+ HelloWorld and Capitalise installation shared scripts illustrate UNO-related macros making use of XSCRIPTCONTEXT global variable. + Python standard output file is not available when running Python macros from Tools - Macros - Run Macro menu. Refer to Input/Output to Screen for more information. +

Module import

+ XSCRIPTCONTEXT is not provided to imported modules. +
+ %PRODUCTNAME Basic libraries contain classes, routines and variables, Python modules contain classes, functions and variables. Common pieces of reusable Python or UNO features must be stored in My macros within (User Profile)/Scripts/python/pythonpath. Python libraries help organize modules in order to prevent module name collisions. Import uno.py inside shared modules. +
+ Genuine BASIC UNO facilities can be inferred using uno.py module. Use Python interactive shell to get a complete module description using dir() and help() Python commands. + + + + Functions + + + Description + + + Mapped in Basic as + + + + + absolutize() + + + Returns an absolute file url from the given urls. + + + + + + + createUnoStruct() + + + Creates a UNO struct or exception given by typeName. + + + CreateUNOStruct() + + + + + fileUrlToSystemPath() + + + Returns a system path. + + + ConvertFromURL() + + + + + getClass() + + + Returns the class of a concrete UNO exception, struct, or interface. + + + + + + + getComponentContext() + + + Returns the UNO component context used to initialize the Python runtime. + + + GetDefaultContext() + + + + + Enum() + getConstantByName() + + + Looks up the value of an IDL constant by giving its explicit name. + + + See API constant groups + + + + + isInterface() + + + Returns True, when obj is a class of a UNO interface. + + + + + + + systemPathToFileUrl() + + + Returns a file URL for the given system path. + + + ConvertToURL() + + +
+ LibreLogo and TableSample installation shared scripts use uno.py module. +

More Python-Basic samples

+ + + + Python UNO + + + Basic UNO features + + + + + ctx = uno.getComponentContext() + smgr = ctx.getServiceManager() + obj = smgr.createInstanceWithContext( .. , ctx) + + + CreateUnoService() + + + + + See Opening a Dialog + + + CreateUnoDialog() + + + + + See Creating a Listener + + + CreateUnoListener() + + + + + See UNO data types + + + CreateUnoValue() + CreateObject() + + + + + + + EqualUnoObjects() + + + + + ctx = uno.getComponentContext() + smgr = ctx.getServiceManager() + + + GetProcessServiceManager() + + + + + def hasUnoInterfaces(obj, *interfaces): + return set(interfaces).issubset(t.typeName for t in obj.Types) + + + + HasUnoInterfaces() + + + + + + + IsUnoStruct() + + + + + ctx = uno.getComponentContext() + smgr = ctx.getServiceManager() + DESK = 'com.sun.star.frame.Desktop' + desktop = smgr.createInstanceWithContext(DESK , ctx) + + + StarDesktop + + + + + desktop = smgr.createInstanceWithContext(DESK , ctx) + doc = desktop.CurrentComponent + + + ThisComponent + + +
+

Importing an embedded Module

+
+ Similarly to %PRODUCTNAME Basic that supports browsing and dynamic loading of libraries, Python libraries can be explored and imported on demand. For more information on library containers, visit %PRODUCTNAME Application Programming Interface (API) or download %PRODUCTNAME Software Development Kit (SDK). + Importing a Python document embedded module is illustrated below, exception handling is not detailed: + + import uno, sys + + def load_library(library_name: str, module_name=None): + """ load library and import module + + Adapted from 'Bibliothèque de fonctions' by Hubert Lambert + at https://forum.openoffice.org/fr/forum/viewtopic.php?p=286213""" + doc = XSCRIPTCONTEXT.getDocument() # current document + url = uno.fileUrlToSystemPath( \ + '{}/{}'.format(doc.URL, 'Scripts/python'+library_name)) # ConvertToURL() + if not url in sys.path: # add path if necessary + sys.path.insert(0, url) # doclib takes precedence + if module_name: # import if requested + return zipimport.zipimporter(url).load_module(module_name) + + def import_embedded_python(): + ui = load_library("my_gui",'screen_io') # add <lib> path + import <module> + ui.MsgBox(sys.modules.keys()) + + g_exportedScripts = (import_embedded_python,) # Public macros + +
+
+ Basic UNO Objects, Functions and Services + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_screen.xhp b/helpcontent2/source/text/sbasic/python/python_screen.xhp new file mode 100644 index 000000000..b88fa923a --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_screen.xhp @@ -0,0 +1,108 @@ + + + + + + Python : Screen Input/Output + /text/sbasic/python/python_screen.xhp + + + + + Python;InputBox + Python;MsgBox + Python;Print + API;script.provider.MasterScriptProvider: Screen Input/Output + API;script.provider.XScript: Screen Input/Output + +

Input/Output to Screen

+ Python standard output file is not available when running Python macros from Tools – Macros - Run Macro... menu. Presenting the output of a module requires the Python interactive console. Features such as input(), print(), repr() and str() are available from the Python shell. + The Alternative Python Script Organizer (APSO) extension offers a msgbox() function out of its apso_utils module. + %PRODUCTNAME Basic proposes InputBox(), Msgbox() and Print() screen I/O functions. Python alternatives exist relying either on %PRODUCTNAME API Abstract Windowing Toolkit, either on Python to Basic function calls. The latter proposes a syntax that is intentionally close to that of Basic, and uses a Python module next to a Basic module. The API Scripting Framework is used to perform Basic, BeanShell, JavaScript and Python inter-languages function calls. +

Python syntax:

+ MsgBox(txt, buttons=0, title=None)
+ InputBox(txt, title=None, default=None)
+ Print(txt) +

Examples:

+ >>> import screen_io as ui + >>> reply = ui.InputBox('Please enter a phrase', title='Dear user', defaultValue="here..") + >>> rc = ui.MsgBox(reply, title="Confirmation of phrase") + >>> age = ui.InputBox('How old are you?', title="Hi") + >>> ui.Print(age) +

Installation:

+ + + Copy screen_io Python module in My macros within <UserProfile>/Scripts/python/pythonpath, + + + Copy uiScripts Basic module in My macros Standard Basic library, + + + Restart %PRODUCTNAME. + + +

screen_io Python module

+ + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + def MsgBox(prompt: str, buttons=0, title='LibreOffice') -> int: + """ Displays a dialog box containing a message and returns a value.""" + xScript = _getScript("_MsgBox") + res = xScript.invoke((prompt,buttons,title), (), ()) + return res[0] + + def InputBox(prompt: str, title='LibreOffice', defaultValue='') -> str: + """ Displays a prompt in a dialog box at which the user can enter text.""" + xScript = _getScript("_InputBox") + res = xScript.invoke((prompt,title,defaultValue), (), ()) + return res[0] + + def Print(message: str): + """Outputs the specified strings or numeric expressions in a dialog box.""" + xScript = _getScript("_Print") + xScript.invoke((message,), (), ()) + + import uno + from com.sun.star.script.provider import XScript + def _getScript(script: str, library='Standard', module='uiScripts') -> XScript: + sm = uno.getComponentContext().ServiceManager + mspf = sm.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", uno.getComponentContext()) + scriptPro = mspf.createScriptProvider("") + scriptName = "vnd.sun.star.script:"+library+"."+module+"."+script+"?language=Basic&location=application" + xScript = scriptPro.getScript(scriptName) + return xScript + +

uiScripts Basic module

+ + Option Explicit + Private Function _MsgBox( prompt As String, Optional buttons As Integer, _ + Optional title As String ) As Integer + _MsgBox = MsgBox( prompt, buttons, title ) + End Function + Private Function _InputBox( prompt As String, Optional title As String, _ + Optional default As String) As String + _InputBox = InputBox( prompt, title, default ) + End Function + Private Sub _Print( msg As String ) + Print msg + End Sub + +
+ + + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_session.xhp b/helpcontent2/source/text/sbasic/python/python_session.xhp new file mode 100644 index 000000000..f8c378dee --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_session.xhp @@ -0,0 +1,158 @@ + + + + + + Python_Session : Session class + /text/sbasic/python/python_session.xhp + + + + + Session;UserName + Session;SharedScripts + Session;SharedPythonScripts + Session;UserProfile + Session;UserScripts + Session;UserPythonScripts + API;PathSubstitution + +

Getting Session Information

+ Computing %PRODUCTNAME user profile and shared modules system file paths can be performed with Python or with Basic languages. BeanShell, Java, JavaScript and Python scripts locations can be derived from this information. +

Examples:

+ With Python shell. + >>> from <the_module> import Session + >>> print(Session.SharedPythonScripts()) # static method + >>> print(Session().UserName) # object property + >>> input(Session().UserProfile) # object property +

From Tools – Macros - Run Macro... menu.

+ + from <the_module> import Session + + def demo_session(): + import screen_io as ui + ui.MsgBox(Session.Share(),title='Installation Share') # static method + ui.Print(Session.SharedPythonScripts()) # static method + s = Session() # instance creation + ui.MsgBox(s.UserName,title='Hello') # object property + ui.Print(s.UserPythonScripts) # object property + + g_exportedScripts = (demo_session,) # public macros + +

With %PRODUCTNAME Basic.

+ + Sub Session_example() + Dim s As New Session ' instance of Session class + Print "Shared scripts location:", s.SharedScripts + MsgBox s.UserName,,"Hello" + Print s.UserScripts, Chr(13), s.UserPythonScripts + End Sub ' Session_example + +

Using COM/OLE and Visual Basic Scripting language.

+ + ' The service manager is always the entry point + ' If there is no office running then an office is started up + Set sm = WScript.CreateObject("com.sun.star.ServiceManager") + ' PathSubstitution service exhibits information to infer + ' <UserProfile|Share>/Scripts/python locations from + Set obj = sm.createInstance("com.sun.star.util.PathSubstitution") + + MsgBox CreateObject("WScript.Network").UserName,, "Hello" + user = obj.getSubstituteVariableValue("$(user)") + MsgBox user & "/Scripts",, "User scripts location" + libO = Replace(obj.getSubstituteVariableValue("$(inst)"), "program/..", "Share") + MsgBox libO & "/Scripts",, "Shared scripts location" + +

Python Session class:

+ + import getpass, os, os.path, uno + + class Session(): + @staticmethod + def substitute(var_name): + ctx = uno.getComponentContext() + ps = ctx.getServiceManager().createInstanceWithContext( + 'com.sun.star.util.PathSubstitution', ctx) + return ps.getSubstituteVariableValue(var_name) + @staticmethod + def Share(): + inst = uno.fileUrlToSystemPath(Session.substitute("$(prog)")) + return os.path.normpath(inst.replace('program', "Share")) + @staticmethod + def SharedScripts(): + return ''.join([Session.Share(), os.sep, "Scripts"]) + @staticmethod + def SharedPythonScripts(): + return ''.join([Session.SharedScripts(), os.sep, 'python']) + @property # alternative to '$(username)' variable + def UserName(self): return getpass.getuser() + @property + def UserProfile(self): + return uno.fileUrlToSystemPath(Session.substitute("$(user)")) + @property + def UserScripts(self): + return ''.join([self.UserProfile, os.sep, 'Scripts']) + @property + def UserPythonScripts(self): + return ''.join([self.UserScripts, os.sep, "python"]) + + Unlike Basic, pathname normalization is performed with Python inside Session class. +

%PRODUCTNAME Basic Session class:

+ + Option Explicit + Option Compatible + Option ClassModule + + Private _ps As Object ' Private member + + Private Sub Class_Initialize() + GlobalScope.BasicLibraries.LoadLibrary("Tools") + Set _ps = CreateUnoService("com.sun.star.util.PathSubstitution") + End Sub ' Constructor + + Private Sub Class_Terminate() + _ps = Nothing + End Sub ' Destructor + + Public Property Get SharedScripts() As String + Dim inst As String, shr As String + inst = ConvertFromURL(_ps.getSubstituteVariableValue("$(prog)")) + shr = Tools.Strings.ReplaceString(inst,"Share","program") + SharedScripts = shr & GetPathSeparator() &"Scripts" + End Property ' Session.sharedScripts + + Public Property Get SharedPythonScripts() As String + sharedPythonScripts = sharedScripts() & GetPathSeparator() &"python" + End Property ' Session.sharedPythonScripts + + Public Property Get UserName() As String ' User account name + userName = _ps.getSubstituteVariableValue("$(username)") + End Property ' Session.userName + + Public Property Get UserProfile() As String ' User profile system path + userProfile = ConvertFromURL(_ps.getSubstituteVariableValue("$(user)")) + End Property ' Session.userProfile + + Public Property Get UserScripts() As String ' User scripts system path + userScripts = userProfile() & GetPathSeparator() &"Scripts" + End Property ' Session.userScripts + + Public Property Get UserPythonScripts() As String ' User Python scripts system path + userPythonScripts = userScripts() & GetPathSeparator() &"python" + End Property ' Session.userPythonScripts + +
+ + + + +
+ +
diff --git a/helpcontent2/source/text/sbasic/python/python_shell.xhp b/helpcontent2/source/text/sbasic/python/python_shell.xhp new file mode 100644 index 000000000..52cea354a --- /dev/null +++ b/helpcontent2/source/text/sbasic/python/python_shell.xhp @@ -0,0 +1,81 @@ + + + + + + Python Interactive Shell + /text/sbasic/python/python_shell.xhp + + + + + Python console + Python Interactive Shell + +
+

Running Python Interactive Console

+
+ The Python interactive console, also known as Python interpreter or Python shell, provides programmers with a quick way to execute commands and try out and test code without creating a file. UNO objects introspection as well as %PRODUCTNAME Python modules documentation can be obtained from the terminal. + + From a full-featured %PRODUCTNAME installed package, use either Basic or Python: +

Using a Basic macro

+ + Sub interpreter_console + Const UNIX = 4 + ps = CreateUnoService("com.sun.star.util.PathSettings") + install_path = ConvertFromURL(ps.Module) + cmd = IIF(GetGuiType()=UNIX,"x-terminal-emulator -e ","") + Shell(cmd + install_path + GetPathSeparator() + "python" ) + End Sub + + +

Using a Python macro

+ + # -*- coding: utf-8 -*- + from __future__ import unicode_literals + + import uno, os, subprocess + + def interpreter_console(): + ctx = XSCRIPTCONTEXT.getComponentContext() + smgr = ctx.getServiceManager() + ps = smgr.createInstanceWithContext("com.sun.star.util.PathSettings", ctx) + install_path = uno.fileUrlToSystemPath(ps.Module) + pgm = install_path + os.sep + "python" # Python shell/console path + subprocess.Popen(pgm) # Start Python interactive Shell + + +

Example output

+ + Python Interactive Console + + + + +

Using the Terminal

+ From a %PRODUCTNAME copy included in a GNU/Linux platform, use the terminal as shown: + whereis or type terminal commands help locate Python interactive console: +
user@computer:~$ type -p python3
/usr/bin/python3
user@computer:~$ /usr/bin/python3
Python 3.7.5 (default, Nov 20 2019, 09:21:52)
[GCC 9.2.1 20191008] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uno
>>> dir(uno)
['Any', 'Bool', 'ByteSequence', 'Char', 'Enum', 'PY2', 'Type', '_ConstantGroup', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_builtin_import', '_component_context', '_impl_getConstantGroupByName', '_uno_extract_printable_stacktrace', '_uno_import', '_uno_struct__eq__', '_uno_struct__getattr__', '_uno_struct__init__', '_uno_struct__ne__', '_uno_struct__repr__', '_uno_struct__setattr__', '_uno_struct__str__', 'absolutize', 'createUnoStruct', 'fileUrlToSystemPath', 'generateUuid', 'getClass', 'getComponentContext', 'getConstantByName', 'getCurrentContext', 'getTypeByName', 'invoke', 'isInterface', 'os', 'pyuno', 'setCurrentContext', 'six_string_types', 'socket', 'sys', 'systemPathToFileUrl', 'traceback', 'warnings']
>>> exit()
user@computer:~$
+
+
+ +

Alternative console

+ Use APSO extension console as an alternative: + + APSO console + +
+ + + PythonShell function in ScriptForge.Exception service + +
+ +
\ No newline at end of file -- cgit v1.2.3